Validates with :if

45,333

Solution 1

I think you have an error in your syntax:

validates :one, :two, :presence => true, :if => :condition_testing?

def condition_testing?
    !(one == 0 && two == 1)
end

There was one :if too many in there... And if I understand correctly you want to have it only validate in case one == 0 && two == 1? Then you condition_testing? is inverted (leave out the !())

If unsure you could try to use pry and insert a breakpoint into your condition_testing? method to see what's going on.

(Please note added ":" before condition testing)

Solution 2

You can validate it in one line:

validates :one, :two, :presence => true, :if => Proc.new { |a| !(a.one == 0 && a.two == 1) }

Solution 3

You are better off using numericality and equal to.

validates :one, :numericality => { :equal_to => 0 }

validates :two, :numericality => { :equal_to => 1 }

http://guides.rubyonrails.org/active_record_validations_callbacks.html#numericality

Solution 4

The problem is that you're using a presence validator with a condition that checks the values of the attributes. This is incorrect. A presence validator checks to make sure those attributes are set. What's worse, you're passing the if option (@Tigraine was correct about your syntax being wrong, by the way), which means whenever that method returns true, the presence won't be checked at all. The way you have this set up, the validator will run only when one is equal to 1 and two is equal to 0. Otherwise, no validations are run at all! I think the best option here is to write a custom validation:

validates :one_and_two

def one_and_two
   errors.add(:base, "one must be 1 and two must be 0") if !(one == 0 && two == 1)
end

This will add an error to the model with the specified message if the condition returns true. (Note: I'm still not clear on what condition is valid and which is invalid, so feel free to change that last part to suit your needs.)

Share:
45,333
James
Author by

James

Updated on July 05, 2022

Comments

  • James
    James almost 2 years

    I'm trying to create a condition in which the attribute 'one' is zero and the attribute 'two' is one, then a model is not valid. But when I make:

    Model.create(:one => 1, :two => 0).valid?
    

    The unit test returns true! Why?

    validates :one, :two, :presence => true, :if => :if condition_testing?
    
    def condition_testing?
        !(one == 0 && two == 1)
    end
    
  • James
    James over 12 years
    No, that is correct. What happens is that whatever the values ​​of attributes always says that the model is valid, and I want that when 'one' and 'two' are 0 and 1 that says the model is invalid.
  • Aldekein
    Aldekein about 9 years
    "which means whenever that method returns true, the presence won't be checked at all" - this is completely wrong. guides.rubyonrails.org/… - the validation runs only if :if method returns true.