This one come up today at the shop.
Say you have the following table:
users (id, admin)
And its got a couple rows in it
(1, 1)
(2, 0)
(3, 1)
(4, NULL)
Now we want to find all non-admin users.
class User < ActiveRecord::Base
end
User.find :all,
:conditions => 'admin = false'
What rows will that return?
(2, 0)
It doesn’t include:
(4, NULL)
because in the database world NULL != false. So we have to rewrite it like:
User.find :all,
:conditions => 'admin = false or admin is null'
That or admin is null part sucks. How can we avoid it?
How about in the users
migration we write:
t.column :admin, :boolean, :default => false
That way all rows will default to false and we can avoid the or admin is null. But do we want logic like that in our database?
Let’s put it in the model:
class User < ActiveRecord::Base
def before_create
if admin.nil?
self.admin = false
end
end
# or 'hiding' the conditional
def before_create
self.admin ||= false
end
end
That’s a pretty lame callback right there.
I say put it in the migration. Databases are designed for ‘default’ values and its less Ruby code I have to write.