我有一个带小数字段的商业模式。其值必须介于0.00和999.99之间。所以我创建了一个十进制字段并为模型添加了验证。
class Order < ApplicationRecord
validates :price, format: { with: /\A\d+(?:\.\d{0,2})?\z/ }, numericality: { greater_than: 0, less_than: 1000 }
end
当我创建一个小数值大于1000或小于0的Order对象时,我得到了我预期的错误,那没关系。我知道 “数字:{greater_than:0,less_than:1000}”验证按预期工作。
然而,当我尝试创建一个十进制值为45.45554或45.45666的Order对象时,rails会将对象持久保存到数据库中,其价格值为45.45。我希望得到一个格式错误,但似乎 格式验证不起作用。
我做错了什么?
任何建议,
感谢。
答案 0 :(得分:1)
答案 1 :(得分:0)
设置者将值转换为十进制。这意味着格式验证将始终通过。
如果您需要验证格式,请在自定义验证中使用read_attribute_before_type_cast
。
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