Whitelisting with the lesser-known #presence_in method

Published in Ruby on Rails development, Programming, RubyComments

Quite often when writing Rails applications we need to do some kind of user input sanitization. We usually end up doing some dull checks across multiple lines. Have a look at this hidden ActiveSupport #presence_in method that provides a convenient way to do whitelisting in just one line.

Whitelisting opening graphic

Let's say your app presents a list of articles and offers multiple ways of sorting them: by upload date, by the number of upvotes and number of comments. One of the possible techniques to support this behavior is defining three types of scopes on your Article model:

class Article < ActiveRecord::Base
  scope :newest,         -> { order(updated_at: :desc) }
  scope :top,            -> { order(upvotes_count: :desc) }
  scope :most_commented, -> { order(comments_count: :desc) }

You'll want to call those scopes depending on the query parameter passed to your controller, e.g. /articles?sort_by=newest.

The easiest way to implement this in our controller would be:

class ArticlesController < ApplicationController
  def index
    @articles = Article.public_send(params[:sort_by])

However, you don't want to send those user inputs directly to your model because you would leave yourself vulnerable to remote code execution. An evildoer could send you a request such as /articles?sort_by=destroy_all and destroy your records.

As a responsible developer, you sanitize that input:

class ArticlesController < ApplicationController
  def index
    @articles = Article.public_send(sorting_technique)


  def sorting_technique
     if %w(newest most_commented top).include? params[:sort_by]

Although this code provides safety, it's still not very nice. I've written similar code many times and have never felt happy about it because I believed it could be shorter.

The #presence_in method to the rescue

That's where the lesser-known method from the ActiveSupport module called Object#presence_in comes in.


Returns the receiver if it's included in the argument. Otherwise, it returns nil. The argument has to be any object which responds to #include?.


def presence_in(another_object)
  self.in?(another_object) ? self : nil


With the presence_in method we can write our sorting_technique method with a nice one-liner:

def sorting_technique
  params[:sort_by].presence_in(%w(newest most_commented top)) || :newest

Its usage doesn't stop here, but I've found it to be most useful when sanitizing user input.

Did you like this?
If you liked this article, subscribe to our newsletter and get more content like this
Share your thoughts
Greetings from our lovely team!
Achievement unlocked
Resize Master