Search code examples
ruby-on-railsvalidationinclusion

Rails 4 Validation: where to put the allow_nil when doing an inclusion?


Are these two implementations functionally equivalent? If so, which is "better?"

  # from a model
  WIDGET_COLORS = %w(red yellow green)
  validates :widget_color,
           inclusion: {in: WIDGET_COLORS, allow_nil: true}

or

  # from a model
  WIDGET_COLORS = %w(red yellow green)
  validates :widget_color,
           inclusion: {in: WIDGET_COLORS},
           allow_nil: true

UPDATE: fixed typo so example reads validates


Solution

  • Firstly validate and validates are different methods - it should be validates here.

    validates will search the supplied hash for so-called _validates_default_keys, which is an internal array [:if, :unless, :on, :allow_blank, :allow_nil , :strict]. All the arguments passed to validates being in this array are treated as common options for all the validators attached to the model with this method. So if you do:

    validates :widget_color,
              inclusion: {in: WIDGET_COLORS},
              uniqueness: true,
              allow_nil: true
    

    allow_nil will affect both of the validators, or is equivalent of:

    validates :widget_color,
              inclusion: {in: WIDGET_COLORS, allow_nil: true},
              uniqueness: {allow_nil: true}
    

    On the other hand with

    validates :widget_color,
              inclusion: {in: WIDGET_COLORS, allow_nil: true},
              uniqueness: true
    

    it will only affect the validator it is defined for (in this case InclusionValidator)