Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To validate or not to validate boolean field

Is there any benefit in having validations for boolean fields of models?

I had a validation for ensuring the presence of a boolean field

validates :boolean_attribute, presence: true

It failed when boolean_attribute was false. I googled around and found these SO questions relating to the issue.

Rails database defaults and model validation for Boolean fields
Rails validates_presence not validating on Boolean?

Then added this validation instead

 validates :field, :inclusion => {:in => [true, false]}

This made me think. Do I need any validations for boolean fields at all? Its value will always be true or false or nil right? Even if someone maliciously try to change it to say, a number, wouldn't the type take care of it? Or is there some safety the above inclusion validation provides?

like image 275
sudo bangbang Avatar asked Jan 13 '16 05:01

sudo bangbang


People also ask

How do you validate a boolean value in Java?

parseBoolean(String s) − This method accepts a String variable and returns boolean. If the given string value is "true" (irrespective of its case) this method returns true else, if it is null or, false or, any other value it returns false.

How do you validate fields in spring boot?

Validation in Spring Boot is done mainly by using Hibernate Validator — an implementation of Java Bean Validation using annotation based constraints. But while Hibernate provides a powerful set of constraint violations checkers out of the box, we'll need to put some effort into handling the exceptions it throws.

What is the use of @valid Annotation in spring boot?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.


2 Answers

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
like image 85
Jordan Running Avatar answered Oct 25 '22 11:10

Jordan Running


You don't need to validate a boolean field, if it's not true it's false.

Just set a "default" in your db so that the bool is always going to have a certain value no matter what:

#db/migrate/add_boolean_column_______.rb
class AddBooleanColumn < ActiveRecord::Migration
   def change
      change_table :table do |t|
         t.boolean :field, default: false
      end
   end
end 

This way, I wouldn't even include any validations. The system will ensure you're either setting it as true or false - which is up to you as the developer.

like image 20
Richard Peck Avatar answered Oct 25 '22 11:10

Richard Peck