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

时间:2022-11-23 10:13:42

I have recently noticed that the method changed? on ActiveRecord objects has changed between Rails 3.2.13 and Rails 4.0.1. The problem is with fields connected to integer fields in database. Let's assume I have model Model with number integer field:

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

# 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               #=> {}

This causes a number of extremely annoying issues with form validations - if a user is trying to change the integer value to have invalid characters (but the type cast will result in the same value as initial one), rails will not invoke save method and none of the validation (including numericality: { only_integer: true }) will be run.

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

I have managed to get around this problem by overriding number_changed? method to super || number.to_s != number_before_type_cast, however this is extremely ugly.

我设法通过覆盖number_changed来解决这个问题?超级||的方法number.to_s!= number_before_type_cast,但这非常难看。

The question is: why was this changed? Is it a bug or is intentional change? How can it be fixed without overriding all meta methods for integer columns?

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

1 个解决方案

#1


1  

I'm not sure on how you're running your validations, but I have a model on my rails app which is called ExtraField and have the following validation:

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

class ExtraField < ActiveRecord::Base

  # stuff

  validates :display_order, numericality: { only_integer: true }

  # more stuff

end

I'm using rails 4.0.5 and I can do the following:

我正在使用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"]}

So, although the record indeed isn't marked as changed ( what seems correct IMHO ), I can still run my validations and check that the model is not valid. Doesn't look like a bug to me, but just an intentional improvement.

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

If your form is only validating if the model is responding true to changed? maybe you should check your controller code. Or if you use a gem to help building the form it could be a bug in that gem I guess.

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

#1


1  

I'm not sure on how you're running your validations, but I have a model on my rails app which is called ExtraField and have the following validation:

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

class ExtraField < ActiveRecord::Base

  # stuff

  validates :display_order, numericality: { only_integer: true }

  # more stuff

end

I'm using rails 4.0.5 and I can do the following:

我正在使用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"]}

So, although the record indeed isn't marked as changed ( what seems correct IMHO ), I can still run my validations and check that the model is not valid. Doesn't look like a bug to me, but just an intentional improvement.

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

If your form is only validating if the model is responding true to changed? maybe you should check your controller code. Or if you use a gem to help building the form it could be a bug in that gem I guess.

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