允许在数字字段中使用逗号

Dav*_*ite 4 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1

这是一个如此愚蠢的问题,我觉得我必须错过一些简单的事情.我有一个带quantity字段的表单.人们在输入数量时会继续输入逗号(例如,他们键入12,000以表示一万二千),因此我想在将数量(12000在示例中)保存到数据库中的整数列之前删除逗号.

到目前为止,我尝试了两种方法.覆盖此SO问题中建议的setter方法

  def quantity=(num)
    num.gsub!(',', '') if num.is_a?(String)
    self[:quantity] = num.to_i
  end
Run Code Online (Sandbox Code Playgroud)

这在某种意义上是有效的.如果我输入12,000数量字段并提交表单,我会12000进入数据库.问题是它还绕过了所有quantity验证.例如,我不再可以验证数量值的存在.这个不好.

我还尝试使用before验证回调(而不是覆盖setter):

  before_validation :sanitize_quantity

  def sanitize_quantity
    # Doesn't wok because quantity.to_i already called by this point.
  end
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为当数量到达回调方法时,Rails已经调用to_i它.这意味着12,000它将在12到达回调时被截断.再次,不好.

除了剥离客户端的逗号外,我还能尝试什么?

作为最后一点,我知道这实际上是一件愚蠢的事情,因为某些国家以不同的方式使用句号和逗号.无论如何我仍然需要这样做.

Tod*_*obs 10

使用类型强制

如果我正确理解你的问题,那你就是想把字符串强制转换为数字.如果是这样,你可以像这样使用显式的强制转换:

validates :quantity, presence: true, numericality: true

def quantity=(num)
  self[:quantity] = num.to_s.scan(/\b-?[\d.]+/).join.to_f
end
Run Code Online (Sandbox Code Playgroud)

测试和例子

请参阅查看其工作原理,您可以在控制台上尝试以下操作.

# String as input.
number = '12,956.05'
number.to_s.scan(/\b-?[\d.]+/).join.to_f
=> 12956.05

# Float as input.
number = 12956.05
number.to_s.scan(/\b-?[\d.]+/).join.to_f
=> 12956.05

# Using an ActiveRecord object.
q = Quantity.new quantity: '12,956.05'
=> #<Quantity id: nil, quantity: 12956.05, created_at: nil, updated_at: nil>
q.save
=> true
Run Code Online (Sandbox Code Playgroud)


Dav*_*ite 9

当我正在阅读我的问题时,我确实想到了这一点.

关键是使用虚拟属性.

class Job < ActiveRecord::Base
  def flexible_quantity
    quantity
  end

  def flexible_quantity=(quantity)
    self.quantity = quantity.gsub(',', '') unless quantity.blank?
  end
 end
Run Code Online (Sandbox Code Playgroud)

然后在表单中,使用虚拟属性.

<%= f.text_field :flexible_quantity %>
Run Code Online (Sandbox Code Playgroud)

现在验证flex_quantity值的存在.

class Job < ActiveRecord::Base
  validates :flexible_quantity, presence: true

  # The cool this is that we can leave the numericality validation on the quantity field.
  validates :quantity, presence: true, numericality: { only_integer: true }
end
Run Code Online (Sandbox Code Playgroud)

  • 我可以获得投票的原因吗? (4认同)