Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails database defaults and model validation for boolean fields

In a Rails model I have an attribute is_subscriber, when I constructed a db migration to add this column to the database I specified the default value to be false:

t.boolean  "is_subscriber",   :default => false

I also specified in the model that this attribute needs to be present:

validates :is_subscriber, presence: true

So why do I get this error when I create a model instance without specifying this attribute?

2012-05-08T21:05:54+00:00 app[web.1]: ActiveRecord::RecordInvalid (Validation failed: Is subscriber can't be blank):
like image 291
Andrew Lauer Barinov Avatar asked May 08 '12 21:05

Andrew Lauer Barinov


People also ask

How do I validate in Ruby on Rails?

This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the :with option. Alternatively, you can require that the specified attribute does not match the regular expression by using the :without option. The default error message is "is invalid".

How does validate work in Rails?

Rails validation defines valid states for each of your Active Record model classes. They are used to ensure that only valid details are entered into your database. Rails make it easy to add validations to your model classes and allows you to create your own validation methods as well.

What is the difference between validate and validates in rails?

validates is used for normal validations presence , length , and the like. validate is used for custom validation methods validate_name_starts_with_a , or whatever crazy method you come up with. These methods are clearly useful and help keep data clean. That test fails.


3 Answers

From here

If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, :in => [true, false] This is due to the way Object#blank? handles boolean values. false.blank? # => true

Or in Rails3 way

validates :field, :inclusion => {:in => [true, false]}
like image 200
Fabio Avatar answered Oct 19 '22 16:10

Fabio


I've solved this with:

validates_presence_of :is_subscriber, :if => 'is_subscriber.nil?'
like image 44
Lazarus Lazaridis Avatar answered Oct 19 '22 15:10

Lazarus Lazaridis


I think it is neater to wrap this in a custom validator.

in /app/validators/is_boolean_validator.rb

class IsBooleanValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, parameters)
    if !parameters.in? [true,false]
      record.errors[attribute] << 'This must be true or false.'
    end
  end
end

then you have to make sure this is loaded by adding the following to /config/application.rb

config.autoload_paths += %W["#{config.root}/app/validators/"]

(don't forget to restart your server to load this)

You can then validate more neatly with

validates: :field1, field2, is_boolean: true
like image 1
Confused Vorlon Avatar answered Oct 19 '22 16:10

Confused Vorlon