Reputation: 473
I have a business model with a decimal field. Its value must be between 0.00 and 999.99. So I have created a decimal field and add validations to the model.
class Order < ApplicationRecord
validates :price, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: { greater_than: 0, less_than: 1000 }
end
When I create the Order object with a decimal value which is greater than 1000 or less than 0, I get the error I expected and that's ok. I can see that "numericality: { greater_than: 0, less_than: 1000 }" validations work as expected.
Howeber, when I try to create an Order object with a decimal value of 45.45554 or 45.45666, rails persists the object to the database with the price value of 45.45. I expect getting a format error, but it seems that format validation doesn't work.
What I'm doing wrong ?
Any suggestions,
Thanks.
Upvotes: 0
Views: 4504
Reputation: 101811
The value is converted to decimal by the setter. Which means that format validation will always pass.
If you need validate the format use read_attribute_before_type_cast
in a custom validation.
class Order < ApplicationRecord
validates :price, numericality: { greater_than: 0, less_than: 1000 }
validates :price_format
PRICE_REGEXP = /\A\d+(?:\.\d{0,2})?\z/.freeze
private
def price_format
unless read_attribute_before_type_cast('price') =~ PRICE_REGEXP
errors.add('price', 'must match the correct format')
end
end
end
Upvotes: 1