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
“Two” you say, with some derision. “Everybody knows that. That’s what a boolean is. It returns
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:
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
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
change_column :wikis, :private, :boolean, :default => false
change_column :wikis, :private, :boolean, :default => nil
Now just remember to reset and re-seed your database:
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.