Use presence


One of the things you quite often see in Rails code bases is code like this:

do_something if !foo.blank?

or

unless foo.blank?
  do_something
end

Sometimes it’s useful to check for blankness, but in my experience it’s much more useful to check for presence. It reads better and doesn’t deal in negations. When using blank? it’s way too easy to use complicated negations.

For some reasons it seems to have escaped people that Rails already defines the opposite of blank? as present?:

do_something if foo.present?

There is also a very common pattern that you see when working with parameters. The first iteration of it looks like this:

name = params[:name] || "Unknown"

This is actually almost always wrong, since it will accept a blank string as a name. In most cases what you really want is something like this:

name = !params[:name].blank? ? params[:name] : "Unknown"

Using our newly learnt trick, it instead becomes:

name = params[:name].present? ? params[:name] : "Unknown"

Rails 3 introduces a new method to deal with this, and you should back port it to any Rails 2 application. It’s called presence, and the definition looks like this:

def presence
  self if present?
end

With this in place, we can finally say

name = params[:name].presence || "Unknown"

These kind of style things make a huge difference in the small. Once you have idiomatic patterns like these in place in your code base, it’s easier to refactor the larger parts. So any time you reach for blank?, make sure you don’t really mean present? or even presence.


4 Comments, Comment or Ping

  1. yhvd

    Well, wouldn’t the cleanest way of using blank? in that situation be

    do_something unless foo.blank?

    instead of the doubly negative if !foo.blank?

    Though I will admit that if foo.present? looks just as good, just as well that presence will also have situations where it look nice.

    January 13th, 2011

  2. Torspo

    I don’t like how that presence thing reads.

    How about:

    def defaulting_to(obj)
    present? ? self : obj
    end

    And then:

    name = params[:name].defaulting_to(“Unknown”)

    December 16th, 2012

Reply to “Use presence”