Bro*_*tse 8 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-4
我最近注意到,changed?ActiveRecord对象上的方法在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将不会调用save方法,也不会调用验证(包括numericality: { only_integer: true })将运行.
我设法通过覆盖number_changed?方法来解决这个问题super || number.to_s != number_before_type_cast,但这非常难看.
问题是:为什么这会改变?这是一个错误还是故意改变?如何在不覆盖整数列的所有元方法的情况下修复它?
我不确定您如何运行验证,但我的 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"]}
因此,尽管记录确实没有标记为已更改(恕我直言,这似乎是正确的),但我仍然可以运行验证并检查模型是否无效。对我来说,这不像是一个错误,而只是一个有意的改进。
如果您的表单仅验证模型是否响应 true,changed?也许您应该检查您的控制器代码。或者,如果您使用 gem 来帮助构建表单,我猜这可能是该 gem 中的错误。
| 归档时间: | 
 | 
| 查看次数: | 926 次 | 
| 最近记录: |