【问题标题】:Rails - regexp validation for number of decimal pointsRails - 小数点的正则表达式验证
【发布时间】:2016-03-06 09:41:45
【问题描述】:

我有一个通过正则表达式验证小数精度的模型:

    class Loan < ActiveRecord::Base
      validates :amount,
                format: {with: /\A\d+(?:\.\d{0,2})?\z/}, numericality: {less_than: 1000000}, allow_blank: true
    end

在 Rails 4.2.4

l = Loan.new
l.amount = 1.1111
l.valid? # false

在 Rails 4.2.5

l = Loan.new
l.amount = 1.1111
l.valid? # true

我的正则表达式中存在问题,该问题被较新版本或 Rails、Rails 验证本身或其他原因暴露?

【问题讨论】:

  • 我认为问题不在于正则表达式,而可能是验证发生了变化。对于您的具体问题,您可以使用 Money gem 来处理货币,这很有帮助;)
  • 仅供参考:如果您不希望1. 有效,请使用{1,2} 而不是{0,2}
  • 我很惊讶能够使用正则表达式验证浮点数。在恕我直言中没有多大意义。这可能是一个错误,已在最新版本中修复。
  • @spickermann 金额的基础数据结构是十进制的,因此验证试图验证十进制精度。从 Rails 3 到现在一直在做这些类型的验证。
  • 小数精度不是你可以改变和验证的。它是为计算机固定的。即使你向它申请to_s,也不会改变这种情况。

标签: ruby-on-rails ruby regex ruby-on-rails-4 ruby-on-rails-4.2


【解决方案1】:
class Loan
  include ActiveModel::Model
  attr_accessor :amount
  validates :amount, format: {with: /\A\d+(?:\.\d{0,2})?\z/}, numericality: {less_than: 1000000}, allow_blank: true
 end

在 Rails 4.2.5 中:

l = Loan.new
l.amount = 1.1111
l.valid? # false

所以这一定来自其他地方。

如果您更改了 Ruby 的版本,那可能是这样。

这可能是 Rails 改变了它处理格式转换的方式(正则表达式适用于字符串,因此给定数字必须在某处进行一些转换)。不过我对此表示怀疑(查看发行说明)。

【讨论】:

    【解决方案2】:

    这可以通过自定义验证而不是正则表达式来实现吗? 比如:

    validates :amount, numericality: {less_than: 1000000}, allow_blank: true
    validate :amount_has_ok_decimal_places
    
    def amount_has_ok_decimal_places
      decimals = amount.to_s.split('.')
      if decimals.size == 2 && decimals.last.size > 2
        errors.add(:amount, "can't be more than 2 decimal places")
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多