以下是我在模型中使用的内容:
before_validation :strip_dollar_sign
validates :amount_due,
:format => { :with => /^\d+??(?:\.\d{0,2})?$/ },
:numericality => {:greater_than => 0}
private
def strip_dollar_sign
self.amount_due = self.amount_due.to_s.tr!('$,','').to_f
end
如果我在Rails控制台中手动运行strip_dollar_sign函数中的行,我得到了我想要的(即400美元最终为400.0)但是当我在我的应用程序中使用实际表单时,值总是最终为0.0。有人抓住了我做错的事吗?
答案 0 :(得分:16)
这里有三个问题:
正如Stefan在his answer中指出的那样,您可能希望删除,
来电中的tr!
,但这不会影响$
的替换1}}。
您正在使用tr!
,并且以不正确的方式使用其返回值。如果没有对原始字符串进行任何更改,tr!
(以及Ruby的大多数!
方法变体)将返回nil
。由于nil.to_f
是0.0
,这就是你得到它的原因(或者可能没有,见下文)。您应该使用tr
。
Rails会自动将赋值参数转换为与其关联的数据库列的正确类型,因此即使在验证之前,您的值也会转换为float,"$400".to_f
为0.0
,并且这就是你的回调所看到的。解决方案是覆盖amount_due=
而不是使用回调:
def amount_due=(value)
value = value.to_s.tr('$', '').to_f
write_attribute(:amount_due, value)
end
答案 1 :(得分:3)
$
后面有一个逗号,因此您要删除$,
而不是$
。
答案 2 :(得分:-2)
我建议在javascript中执行此操作。 Rails似乎对表单助手有些神奇,它会将数字数据库类型支持的字段中的任何非数字值转换为0.0。愚蠢,我知道。