roman
roman

Reputation: 5210

Validation fails when using validates_presence_of and validates_numericality_of

I need to validate data in my model and then test this model using rspec:

Here is the validation in model:

validates_presence_of :sales_price
validates_presence_of :retail_price

validates_numericality_of :sales_price, :greater_than => 0
validates_numericality_of :retail_price,:greater_than => 0
validates_numericality_of :sales_price, :less_than => :retail_price,
                                          :message => "must be less than retail price."

when i'm trying to test tho model like this

it { should validate_presence_of :sales_price }
it { should validate_presence_of :retail_price }
it { should validate_numericality_of :sales_price }
it { should validate_numericality_of :retail_price }

I get this error

Failure/Error: it { should validate_presence_of :retail_price }
 ArgumentError:
   comparison of Float with nil failed
 # ./spec/models/offer_option_spec.rb:19:in `block (2 levels) in <top (required)>'

How can i solve this?

Upvotes: 2

Views: 2838

Answers (2)

roman
roman

Reputation: 5210

Thank you for your answer.

I finally got this.

validates_numericality_of :sales_price, :greater_than => 0,
                        :allow_blank => true
validates_numericality_of :retail_price, :greater_than => 0,
                        :allow_blank => true
validates_numericality_of :sales_price, :less_than => :retail_price,
                        :if => Proc.new { |o| !o.retail_price.nil? } ,
                        :message => "can't be greater than retail price."

Now i got another problem. I'm using rails.validation.js which helps me to perform client side validations. Everything is ok if you use something like this in your numerical validator:

:greater_than => 0

validation.js creates a function that checks if the value in the field is greater than 0. The function is created like that:

new Function("return " + element.val() + CHECKS[check] + options[check])()))

element is my input field, CHECKS contains different hash: less_than : <, greater_than : >, etc options[check] contains some value that is passed into validator(:greater_than => 0, zero in this case, options[check] is less_than : '0'). But when i use something else instead of a value i get an error:

Uncaught ReferenceError: retail_price is not defined 

I tried something like this

validates_numericality_of :sales_price, :less_than => Proc.new{ self.retail_price },
                        :if => Proc.new { |o| !o.retail_price.nil? } ,
                        :message => "can't be greater than retail price."

but the object doesn't exist when the validation is performed, so self just points to the class and retail_price doesn't exist.

what would you recommend to solve the problem?

Upvotes: 4

Nick
Nick

Reputation: 2413

@sled is correct that the nil check is built into validates_numericality_of and is enabled by default, so it's unnecessary to have both requirements.

One other thing to note is that sales price really is validating numericality twice which might be causing a problem. I would instead change it to

validates_numericality_of :sales_price, :greater_than => 0, :less_than => :retail_price, :message => "must be less than retail price."

Upvotes: 3

Related Questions