before_destroy回调未在生产模式下注册

时间:2012-12-03 03:53:00

标签: ruby-on-rails activerecord callback

我曾经可以通过./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回调?

谢谢!

1 个答案:

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