ActiveRecord::Dirty和Rake
ActiveRecord::Dirty和Rake
我在一个Rails项目中有一个模型(我们称之为A),它在before_save上使用ActiveRecord::Dirty的a_changed?函数检查一个属性(我们称之为a)。我想在一个Rake任务中保存A的实例,但只包括:environment是不够的 - 我在Rake任务中收到一个\"在A上未定义a_changed?方法\"的消息。如何让ActiveRecord在Rake任务中记住ActiveRecord::Dirty呢?\nRails版本是2.3.11\n鉴于这是一堆相当密集的信息,下面是解释:\n
- \n
- 我有一个名为A的模型,它有一个名为a的属性。
- 模型A定义了一个before_save触发器,调用了ActiveRecord::Dirty在Rails环境中添加的a_changed?方法。从控制器调用这个方法没有问题。
- 然而,在我的Rake任务中,before_save触发器中的a_changed?调用会引发NoMethodError异常,可能是因为[:environment]的要求不足以包含ActiveRecord::Dirty。我的问题是如何避免这种情况发生(我的解决方法是在before_save中捕获NoMethodError,这是一个明显的hack)。
\n
\n
\n
问题的出现原因:该问题是由于在Rake任务中无法访问ActiveRecord::Dirty的方法引起的。作者想要在Rake任务中访问blah_changed?方法,但是无法实现。
解决方法:为了确定对象有哪些方法,可以执行以下操作:
desc "This is a Rake Task" task :some_taskname, [:some_arg] => :environment do |t, args| foo = A.find(11111) p foo.methods end
这将打印出可用方法的列表。如果数组中包含:some_attr_changed?(其中some_attr是一个属性),那么可以确定ActiveRecord::Dirty在Rake任务中正常工作。如果这些方法在数组中不显示,那么你的假设是正确的。
此外,可以尝试在任务中添加以下行:`p A.ancestors`,你会看到该类确实继承了`ActiveRecord::AttributeMethods::Dirty`和`ActiveModel::Dirty`,因此它确实继承了这些模块的方法。