【问题标题】:Changing data format with before_validation doesn't work使用 before_validation 更改数据格式不起作用
【发布时间】:2015-07-11 22:13:37
【问题描述】:

我将模型实例的一些属性保存为浮点数,但我的应用程序必须使用逗号而不是点来处理来自表单的输入(例如,10,99 应保存为 10.99)。 我正在尝试使用 before_validation 回调来做到这一点,但我无法使其正常工作 - 逗号输入无法通过验证,我不断收到 price/size2 is not a number 错误。

class Advert < ActiveRecord::Base    

before_validation do
  normalize(self.price) if is_number?(self.price)
  normalize(self.size2) if is_number?(self.size2)
end

validates :price, presence: true, numericality: true
validates :size2, numericality: true

def is_number?(string)
  true if Float(string) rescue false
end

def normalize(number)
  number.to_s.gsub!(',', '.').to_f
end

任何帮助将不胜感激。

【问题讨论】:

    标签: ruby-on-rails validation ruby-on-rails-4 callback


    【解决方案1】:

    我还没有测试过,但我认为你实际上并没有修改 pricesize2,因为你正在 gsub!ing 数字并且没有将值返回到 2 个属性。

    这样的事情怎么样:

    class Advert < ActiveRecord::Base
      before_validation :string_to_float
    
      validates :price, presence: true, numericality: true
      validates :size2, numericality: true
    
      def is_number?(string)
        true if Float(string) rescue false
      end
    
      def normalize(number)
        number.to_s.gsub(',', '.').to_f
      end
    
      def string_to_float
        self.price = normalize(self.price) if is_number?(self.price)
        self.size2 = normalize(self.size2) if is_number?(self.size2)
      end
    end
    

    【讨论】:

    • 谢谢,那当然是报错了,但是改正后,逗号的格式还是不能通过校验。测试显示,如果输入为'12,2',则保存的值为'12.0',所以看起来是在调用normalize方法之前将输入转换为float。
    【解决方案2】:

    改用自定义设置方法:

    class Advert
      def price=(val)
         @price = val.is_a?(Float) ? val : val.to_f  
      end 
    end
    

    【讨论】:

    • 我正在运行ruby 2.1.5p273,而在使用.to_f 时,我实际上不需要将, 替换为.。需要注意的一件事是,在某些语言环境中,逗号用于表示千:10,001(万一)。
    【解决方案3】:

    由于我无法通过 Rails 回调处理小数分隔符更改,我只是写了一个简单的 jQuery 解决方法,也许它会帮助某人:

    normalize_input = ->
      $('form').submit ->
        normalized_price = $('#advert_price').val().replace(',', '.') # advert_price is a form input
        normalized_size2 = $('#size2input').val().replace(',', '.') # just like the size2input
        $('#advert_price').val(normalized_price)
        $('#size2input').val(normalized_size2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-23
      • 2017-11-20
      • 2011-12-02
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      相关资源
      最近更新 更多