The Value of Ruby Booleans – Binary or Not?

The Situation

So here’s a problem you may have come across. You’ve migrated your Rails database and included a column that uses a boolean value. Lets call that attribute public. So… How many values can public have?

“Two” you say, with some derision. “Everybody knows that. That’s what a boolean is. It returns true or false. It’s just like ‘Yes’ or ‘No’. ‘On’ or ‘Off’. It’s BI – NAR – Y.”

Yes, yes. I thought the same. Until recently. And it bit me.

I had a a conditional flow that tested a boolean called public?. That is, does public = true. And I got the answers I expected.

Then I tested public for false. And I got a bit more than expected.

You see, I made a simple mistake. I did not set a default value for my boolean attribute. And thus, I actually had three states of value in play:

  • true
  • false
  • nil

This caused me endless confusion and pain. But luckily, the fix was pretty easy.

Fixing the Problem

Here’s the short answer – always give your boolean attribute a default value. That way you eliminate the nil state and can focus on the expected true versus false states. Note the default part at the end of the line below that specifies yoru desired default value.

add_column :accounts, :boolean, default: true

But what if, like me, you had already built and migrated your table into the database?

The answer is [pretty easy]. You basically just add another migration to fix your existing boolean and add a default value. Mine looked like this:

rails g migration add_default_value_to_private

And the resulting migration was modified to the following:

class AddDefaultValueToPrivate < ActiveRecord::Migration def up change_column :wikis, :private, :boolean, :default => false
end

def down
change_column :wikis, :private, :boolean, :default => nil
end
end

Now just remember to reset and re-seed your database:
rake db:reset

Take Aways

Not so bad. That was a quick fix to a frustrating problem. So remember:

  • give your booleans default values
  • avoid getting into the [three state trap]

Take care and code well.