如何在Rails中验证前从值中删除美元符号?

时间:2012-06-18 14:13:30

标签: ruby-on-rails ruby

以下是我在模型中使用的内容:

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。有人抓住了我做错的事吗?

3 个答案:

答案 0 :(得分:16)

这里有三个问题:

  • 正如Stefan在his answer中指出的那样,您可能希望删除,来电中的tr!,但这不会影响$的替换1}}。

  • 您正在使用tr!,并且以不正确的方式使用其返回值。如果没有对原始字符串进行任何更改,tr!(以及Ruby的大多数!方法变体)将返回nil。由于nil.to_f0.0,这就是你得到它的原因(或者可能没有,见下文)。您应该使用tr

  • Rails会自动将赋值参数转换为与其关联的数据库列的正确类型,因此即使在验证之前,您的值也会转换为float,"$400".to_f0.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。愚蠢,我知道。