我曾经可以通过./config/initializers/active_record_base.rb中的以下代码为我的应用中的每个ActiveRecord实例注册一个before_destroy回调...
class ActiveRecord::Base
before_destroy :enumerate_descendants
def enumerate_descendants(args={})
# code...
end
end
但是现在,在Rails 3.2.9和ruby 1.9.3p327应用程序中,这仅适用于开发模式而非生产。 (从我的控制器我调用destroy而不是删除,顺便说一句。)一些证明:
localhost:my_app me$ RAILS_ENV=development rails console
Loading development environment (Rails 3.2.9)
1.9.3-p327 :001 > Person._destroy_callbacks
=> [<ActiveSupport::Callbacks::Callback:0x007fbdde8f2890 @klass=ActiveRecord::Base, @kind=:before,
@chain=[...], @per_key={:if=>[], :unless=>[]}, @options={:if=>[], :unless=>[]},
@raw_filter=:enumerate_descendants, @filter=:enumerate_descendants, @compiled_options="true", @callback_id=12>]
localhost:my_app me$ RAILS_ENV=production rails console
Loading production environment (Rails 3.2.9)
1.9.3-p327 :001 > Person._destroy_callbacks
=> []
如果我在./environments/production.rb中使用config.cache_classes = false,则回调会在生产模式下注册,但这对于生产应用来说显然是一个问题...
那么,除了我所有模型的基类之外,任何想法如何在生产模式下为所有ActiveRecord实例注册一个before_destroy回调?
谢谢!
答案 0 :(得分:1)
正如我在评论中写的那样,这可能是因为你的模型在之前加载了你在ActiveRecord :: Base中添加了“before_destroy”。在开发环境中(当config.cache_classes = false
时)重新加载模型(对于每个请求?),然后“before_destroy”已经在ActiveRecord :: Base上注册。
我在旧的Rails中对此进行了测试,但我的行为相同
您必须找到在ActiveRecord :: Base上注册“before_destroy”的代码的位置,以便在加载任何模型之前完成。
如果您自己测试一下,例如在控制台中执行require 'one_of_your_models'
以查看它是否适用于重新加载,这是不够的,您必须在重新加载之前执行Object.send(:remove_const, :OneOfYourModels)
(Rails在重新加载模型之前执行此操作)。