after_find回调无法正常工作

时间:2014-11-05 23:08:55

标签: activerecord ruby-on-rails-4

我安装了Rails 4.1.6。

模型Report

after_find :convert_decimal_to_float

def convert_decimal_to_float
    self.mag = self.mag.to_f
end

在rails控制台中:

2.1.2 :001 > r = Report.last
...
2.1.2 :002 > r.mag
 => #<BigDecimal:5032730,'0.31E1',18(36)>

但是,如果我使用r.mag.to_f,它可以正常工作:

2.1.2 :003 > r.mag.to_f
 => 3.1 

问题是,为什么我的after_find回调在这里没有正常工作?

1 个答案:

答案 0 :(得分:1)

你的after_find回调实际上正常工作,但因为你的数据库列是DECIMAL类型,所以它总是保存为BigDecimal。就像该列是FLOAT类型一样,如果您尝试将BigDecimal数字保存到它,它将转换并保存为浮点数。

如果不确切地知道为什么在“找到”对象时需要转换,很难就适当的解决方法提出任何建议,但这里有几个选项:

第一个选项:

您可以在数据库中创建两列。 DECIMAL列和FLOAT列。

<强>移植

   add_column('report','mag', :decimal,:precision => 11, :scale => 9)    # I've just used random precision and scale, I'm not sure what you would need
   add_column('report','mag_floating_point', :float)

报告模型

after_find :convert_decimal_to_float

    def convert_decimal_to_float
      self.mag_floating_point = self.mag    # this will convert decimal number to float and "Assign"
      self.save                             # you will still need to save the object as the value has only been assigned
    end

第二个选项:

我认为第二种选择会更好。

报告模型

attr_accessor :mag_floating_point   # Virtual attribute

    def convert_decimal_to_float
      self.mag_floating_point = self.mag.to_f       
    end

您现在可以通过虚拟属性访问浮点数,但请记住它不会持续存在。在我看来,这更清洁了。