It is necessary that validation takes place only if the field is 1 or 25. Tried this:

validates :x, numericality: { equal_to: (1 || 25) } 

... but it does not work.

  • I completely shoveled the question, check if it matches what you asked. In particular, does the example look like what you tried. - D-side
  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

1 answer 1

Do you know what is (1 || 25) ? And check in the IRB:

 (1 || 25) # => 1 

What a twist! But why?

Because || returns the first (left) operand, which is not nil and not false . This is "short-closed OR" , which always returns one of its operands (regardless of their types! It can break the brain in some cases):

  • Left is calculated, if it is not false and not nil , it returns
  • ... otherwise, the right one is calculated and returned (whatever it is)

And if you look closely, then for Boolean operands (only true and false ) this is still the usual "or", it acts in conditions in the expected way. But for other types, this operator acquires a completely different meaning.

 false || nil # => nil 1 || nil # => 1 nil || false # => false "wat" || nil # => "wat" 0 || "wat" # => "wat" -- 0 ведёт себя как true! 

Another interesting special effect: when the operands are not values, but expressions that return values. If after calculating the left operand the result is already known, then the right operand will not even be calculated.

 true || puts('Это не выведется!') 

This is what I need.

... in fact , you got a validation for equality 1 . Oops.


Here we need more validation for inclusion , belonging to a set of values:

 validates :x, inclusion: { in: [1, 25] }