Zero is not always truthy in the Rails ecosystem

In Ruby, the numeric 0 is a truthy value, meaning it is converted to true when evaluated in a boolean expression. This is unlike languages such as JavaScript and Python, where the numeric 0 is falsy (ie. evaluates as false in a boolean expression). This is also a departure from the underlying hardware that our programs run on, where a 1 bit represents true and a 0 bit represents false. We can check that 0 is truthy in an irb console by using a double bang to to convert 0 to its boolean value:

~ irb
3.0.2 :001 > !!0
 => true 

In Ruby, nil and false are the only falsy values, which is an elegant part of the language’s design. This philosophy of 0 as truthy is seen in some of ActiveSupport’s widely-used methods:

3.0.2 :001 > 0.present?
 => true 
3.0.2 :002 > 0.blank?
 => false 

0.present? returns true because it is not blank. 0 is not blank because it is not logically false, and not considered to be “empty” the way " ", { }, and [] are.

However, did you know that this philosophy of “0 as truthy” doesn’t extend to all methods provided by ActiveRecord and ActiveSupport?

For each attribute on an ActiveRecord object, ActiveRecord generates a “query method” that ends with a ? character. This method checks for the presence of that attribute. For example, if we have a model named Person with an attribute called age, ActiveRecord generates a method named age? that behaves like so:

p = Person.new
p.age = nil
p.age? # returns false
p.age = 18
p.age? # returns true

How does .age? behave when age is set to 0?

p.age = 0
p.age? # returns false

This behaviour (0 returning false when being read in a query method) is well-documented in the ActiveRecord::Base documentation, and its source code in the ActiveRecord codebase is easy to follow. In some cases, this can result in more readable code – for example, if we have a BankAccount model with a balance attribute, we could check if it has a non-zero balance by calling the .balance? method. However, it’s a departure from the 0 as truthy” design philosophy, and so it’s an interesting edge case to consider in the Rails ecosystem!

Start your journey towards writing better software, and watch this space for new content.