Ruby on Rails十进制属性验证

时间:2017-08-22 21:43:29

标签: ruby-on-rails ruby validation decimal

我有一个带小数字段的商业模式。其值必须介于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。我希望得到一个格式错误,但似乎 格式验证不起作用。

我做错了什么?

任何建议,

感谢。

2 个答案:

答案 0 :(得分:1)

价格区域的精确度是多少?通过docs

precision定义小数字段的精度,表示数字中的总位数。

我假设价格只有2的精度,这就是为什么它会四舍五入。

答案 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