4

我想检查模型上的属性何时发生变化。我曾尝试在保存之前检查值 != 表单上的值,但该代码确实很难看,有时无法正常工作。与使用 update_column 相同,它不会在我的模型类中进行验证。如果我使用 update_attributes 而不做其他事情,我将无法根据我的理解检查字段何时更新。从我对 Stack Overflow 和其他网站的网络研究看来,使用 ActiveModel Dirty 是可行的方法。

我看过这个:http ://api.rubyonrails.org/classes/ActiveModel/Dirty.html

我希望使用它来检查使用 update_attributes 后模型上的布尔标志是否发生了变化。我尝试按照包含的链接中所述进行最低限度的实施。我在我的 ActiveRecord 类中添加了以下内容:

include ActiveModel::Dirty

define_attribute_methods [:admin]

我尝试添加我想要跟踪的三个属性。我从一个属性开始,看看我是否可以让它工作。运行 rspec 测试时收到以下错误。一旦我删除了论点,我就没有错误了。

Exception encountered: #<ArgumentError: wrong number of arguments (1 for 0)>

删除参数后,我决定使用 admin 而不是 name 在我的模型中包含类似的方法。其他 Rspec 测试在 save 方法上中断。但是我觉得问题在于我如何实现 ActiveModel Dirty。

我读过其他 Stack Overflow 帖子,评论者说这包含在 3.2.8 中,所以我从 3.2.6 升级到 3.2.8。我不明白这意味着什么,所以在出现错误后我决定只保留 include ActiveModel::Dirty 语句并尝试使用 admin_changed? 当然它没有用。

除了我在此处包含的链接之外,我无法找到有关如何为此进行初始设置的任何信息。我发现的所有其他研究都假设初始设置是正确的,并且更新到当前稳定版本的 Rails 可以解决他们的问题。

任何帮助将不胜感激如何实现这一点。执行链接中所述的最小实现不起作用。也许我还缺少其他东西。

4

2 回答 2

8

问题似乎是 ActiveRecord 重新定义了define_attribute_methods接受 0 个参数的方法(因为 ActiveRecord 自动为数据库表中的每一列创建属性方法):https ://github.com/rails/rails/blob/master/activerecord/lib/ active_record/attribute_methods.rb#L23

这覆盖了define_attribute_methodsActiveModel 提供的方法:https ://github.com/rails/rails/blob/master/activemodel/lib/active_model/attribute_methods.rb#L240

解决方案:

我想出了一个对我有用的解决方案......

将此文件另存为lib/active_record/nonpersisted_attribute_methods.rbhttps ://gist.github.com/4600209

然后你可以做这样的事情:

require 'active_record/nonpersisted_attribute_methods'
class Foo < ActiveRecord::Base
  include ActiveRecord::NonPersistedAttributeMethods
  define_nonpersisted_attribute_methods [:bar]
end

foo = Foo.new
foo.bar = 3
foo.bar_changed? # => true
foo.bar_was # => nil
foo.bar_change # => [nil, 3]
foo.changes[:bar] # => [nil, 3]

但是,当我们这样做时,看起来我们会收到警告:

DEPRECATION WARNING: You're trying to create an attribute `bar'. Writing arbitrary attributes on a model is deprecated. Please just use `attr_writer` etc.

所以我不知道这种方法是否会在 Rails 4 中中断或更难......

也可以看看:

于 2013-01-22T21:00:47.287 回答
-3

尝试添加 =,如下所示:

define_attribute_methods = [:admin]

这种改变对我有用。不确定这是否与有关?

于 2012-11-15T23:52:22.883 回答