Whether or not you should validate a boolean attribute for inclusion in [ true, false ]
depends entirely on your use case.
You've correctly identified that, in the absence of validation of other code, a boolean field in Rails will always be (after type coercion) true
, false
, or nil
. Rails won't coerce nil
to false
. If you set a model's boolean attribute to nil
and save it, the attribute will be nil
, not false
, when you fetch the it from the database later.
You can think of nil
as a "third state" for a boolean field. Consider a simple survey app that lets users save an unfinished survey to complete later. Suppose a user saves an incomplete survey with the question "Do you eat meat?" unanswered. You don't want to store false
in the database because that would indicate that the user answered "no." When the user comes back to finish the survey you want that question to still be unanswered, so you want to store nil
in the database.
In cases like the above, it's appropriate (and necessary) not to validate for inclusion in [ true, false ]
.
However, as a rule of thumb I would say that in all other cases—i.e. in any case where you don't have a specific need for nil
values—you should validate boolean fields for inclusion in [ true, false ]
.
Of course, if you do allow nil
you'll need to be careful because, as you know, nil
is a falsey value in Ruby. You'll have to explicitly check for "nilness" in places where you might otherwise rely on a value's truthiness or falsiness. That is, instead of this:
if !is_meat_eater
unanswered_questions << :is_meat_eater
end
...which will not behave as intended if is_meat_eater
is false
, you'll need to explicitly check for nil
:
if is_meat_eater.nil?
unanswered_questions << :is_meat_eater
end
null: false
on the column – Taryn Easttrue
orfalse
but notnil
then you want to use the validation. Iftrue
,false
, andnil
are all okay, you don't need the validation. Which of those is correct for you depends entirely on your use case. – Jordan Running