I was trying to write a validation for Rails to ensure that a price entered on a form was greater than zero. It works…sort of. The problem is that when I run it, val
is turned into an integer, so it thinks that .99 is less than .1. What's going on, and how should I fix the code?
class Product < ActiveRecord::Base
protected
def self.validates_greater_than_zero(*attr_names)
validates_each(attr_names) do |record, attr, val|
record.errors.add(attr, "should be at least 0.01 (current val = #{val.to_f})") if val.nil? || val < 0.01
end
end
public
validates_presence_of :title, :des开发者_如何学Pythoncription, :image_url
validates_numericality_of :price
validates_greater_than_zero :price
end
If the original string value is cast to an integer, it will be rounded down. So “0.99” gets rounded down to 0, which is obviously less than 0.01. You should compare against the original string, which you can get from the <attr>_before_type_cast
method.
Something like this should work:
validates_each(attr_names) do |record, attr, val|
if record.send("#{attr}_before_type_cast").to_f < 0.01
record.errors.add(attr, "error message here")
end
end
You can change
validates_numericality_of :price
to
validates_numericality_of :price, :greater_than_or_equal_to => 0.01
it seems to do what your validates_greater_than_zero
validator wants to do.
精彩评论