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)
当我正在阅读我的问题时,我确实想到了这一点.
关键是使用虚拟属性.
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)