1

我曾经能够通过 ./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 应用程序中,这只适用于开发模式,不适用于生产模式。(顺便说一句,从我的控制器中,我调用的是销毁而不是删除。)一些证据:

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 回调?

谢谢!

4

1 回答 1

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 在重新加载模型之前执行此操作)。

于 2012-12-03T18:26:04.310 回答