Rails 3.2.13 vs Rails 4.0.1 - 改变了吗?方法改变了?

时间:2014-04-13 13:31:00

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4

我最近注意到,ActiveRecord对象上的方法changed?在Rails 3.2.13和Rails 4.0.1之间发生了变化。问题是连接到数据库中的整数字段的字段。假设我的模型Model带有number整数字段:

# Rails 3.2.13

m = Model.last
m.number                #=> 5
m.number = '5hello'
m.number                #=> 5
m.number_changed?       #=> true
m.changed?              #=> true
m.changes               #=> {:number => [5,5]}

# Rails 4.0.1

m = Model.last
m.number                #=> 5
m.number = '5hello'
m.number                #=> 5
m.number_changed?       #=> false
m.changed?              #=> false
m.changes               #=> {}

这会导致表单验证时出现一些非常烦人的问题 - 如果用户试图将整数值更改为无效字符(但类型转换将导致与初始值相同的值),rails将不会调用{ {1}}方法并且不会运行任何验证(包括save)。

我设法通过将numericality: { only_integer: true }方法覆盖到number_changed?来解决此问题,但这非常难看。

问题是:为什么这会改变?这是一个错误还是故意改变?如何在不覆盖整数列的所有元方法的情况下修复它?

1 个答案:

答案 0 :(得分:1)

我不确定你是如何运行验证的,但我的rails应用程序上有一个名为ExtraField的模型,并进行了以下验证:

class ExtraField < ActiveRecord::Base

  # stuff

  validates :display_order, numericality: { only_integer: true }

  # more stuff

end

我正在使用rails 4.0.5,我可以执行以下操作:

e = ExtraField.first
e.display_order           #=> 1
e.valid?                  #=> true
e.errors.messages         #=> {}
e.display_order = '1banana'
e.display_order           #=> 1
e.display_order_changed?  #=> false
e.changed?                #=> false
e.valid?                  #=> false
e.errors.messages         #=> {:display_order=>["is not a number"]}

所以,虽然记录确实没有标记为已更改(看似正确的恕我直言),但我仍然可以运行我的验证并检查该模型是否无效。对我来说看起来不是一个错误,但只是一个有意识的改进。

如果您的表单仅验证模型是否响应changed?,则可能应检查控制器代码。或者,如果您使用宝石来帮助构建表单,我猜这可能是宝石中的错误。