rails validation: :allow_nil and :inclusion both needed at the same time

Ruby on-RailsRubyValidationInclusion

Ruby on-Rails Problem Overview


Usually the field 'kind' should be allowed blank. but if it is not blank, the value should included in ['a', 'b']

validates_inclusion_of :kind, :in => ['a', 'b'], :allow_nil => true

The code does not work?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

This syntax will perform inclusion validation while allowing nils:

validates :kind, :inclusion => { :in => ['a', 'b'] }, :allow_nil => true

Solution 2 - Ruby on-Rails

In Rails 5 you can use allow_blank: true outside or inside inclusion block:

validates :kind, inclusion: { in: ['a', 'b'], allow_blank: true }

or

validates :kind, inclusion: { in: ['a', 'b'] }, allow_blank: true

tip: you can use in: %w(a b) for text values

Solution 3 - Ruby on-Rails

check also :allow_blank => true

Solution 4 - Ruby on-Rails

If you are trying to achieve this in Rails 5 in a belongs_to association, consider that the default behaviour requires the value to exist.

To opt out from this behaviour you must specify the optional flag:

belongs_to :foo, optional: true 

validates :foo, inclusion: { in: ['foo', 'bar'], allow_blank: true } 

Solution 5 - Ruby on-Rails

In Rails 5.x you need, in addition to the following line, to call a before_validation method:

validates_inclusion_of :kind, :in => ['a', 'b'], :allow_nil => true

The before_validation is needed to convert the submitted blank value to nil, otherwise '' is not considered nil, like this:

  before_validation(on: [:create, :update]) do
    self.kind = nil if self.kind == ''
  end

For database disk space usage it is of course better to store nil's than storing empty values as empty strings.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanielView Question on Stackoverflow
Solution 1 - Ruby on-RailsMattView Answer on Stackoverflow
Solution 2 - Ruby on-RailsvasylmeisterView Answer on Stackoverflow
Solution 3 - Ruby on-RailsOrenView Answer on Stackoverflow
Solution 4 - Ruby on-RailsFabrizio ReginiView Answer on Stackoverflow
Solution 5 - Ruby on-RailsW.M.View Answer on Stackoverflow