user297008
user297008

Reputation:

Writing a rails validator with integer

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, :description, :image_url
  validates_numericality_of :price
  validates_greater_than_zero :price
end

Upvotes: 4

Views: 1043

Answers (2)

Corey
Corey

Reputation: 2243

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.

Upvotes: 1

Todd Yandell
Todd Yandell

Reputation: 14696

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

Upvotes: 1

Related Questions