ActiveRecord全局回调函数适用于所有模型
在Rails 4中,观察者功能从核心中删除了。使用rails-observers gem作为替代。以下是使用观察者的示例代码:
class AuditObserver < ActiveRecord::Observer observe ActiveRecord::Base.send(:subclasses) def after_save(record) AuditTrail.new(record, "UPDATED") end end
要激活观察者,需要在config/application.rb文件中的config.active_record.observers配置设置中列出它。例如:
config.active_record.observers = :audit_observer
有人提出了一个问题,如何动态获取模型列表并传递给observe方法。在stackoverflow上找到了解决方法,使用以下代码可以获取所有模型的集合:
Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file }
将此代码添加到observe方法之前可以确保所有模型都被加载。当然,如果所有模型都在models目录中,这段代码应该可以正常工作。
另外,还某些情况下在Rails 4中,可以简化observe方法的调用,只需要使用`observe ActiveRecord::Base`即可观察到子类的创建,无需预加载或检查子类或后代。
在Rails中,可以使用观察者来为所有模型添加全局回调。在Rails 4中,观察者功能已经从核心中移除,需要使用rails-observers gem作为替代。为了确保所有模型都被观察到,可以在observe方法之前添加代码来动态获取模型列表并加载。
问题的出现原因是在Rails 3中,当观察者被加载时,有些模型可能还没有被加载。文档中提到可以通过重写observed_classes方法来动态获取Active Record的子类。
解决方法是使用ActiveRecord::Base.descendants
来替代私有方法调用,这样可以更好地实现获取所有模型的功能。
以下是代码示例:
class AuditObserver < ActiveRecord::Observer def self.observed_classes ActiveRecord::Base.descendants end end
通过以上方法,我们可以在Rails 3中实现全局的ActiveRecord回调函数。