7

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

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 结尾。有人发现我做错了什么吗?

4

3 回答 3

17

这里有三个问题:

  • 正如 Stefan 在他的回答中指出的那样,您可能希望,tr!通话中删除 ,尽管它不会影响替换 a $

  • 您正在使用tr!,并且以不正确的方式使用其返回值。tr!(连同大多数 Ruby 的!方法变体)就地改变字符串并nil在没有进行任何更改时返回。因为nil.to_fis 0.0,这就是你得到它的原因(或者可能没有,见下文)。您应该改用tr.

  • Rails 自动将赋值参数转换为与其关联的数据库列的正确类型,因此即使在验证之前,您的值也会被转换为浮点数,并且"$400".to_f0.0,这就是您的回调所看到的。解决方案是覆盖amount_due=而不是使用回调:

    def amount_due=(value)
      value = value.to_s.tr('$', '').to_f
      write_attribute(:amount_due, value)
    end
    
于 2012-06-18T14:26:46.600 回答
3

后面有一个逗号,$所以你要删除$,而不是$.

于 2012-06-18T14:17:31.390 回答
-2

我建议在 javascript 中执行此操作。Rails 似乎对表单助手做了一些魔术,它将由数字数据库类型支持的字段中的任何非数字值转换为 0.0。愚蠢,我知道。

于 2014-02-13T00:55:59.697 回答