1

在 Rails 的初始化程序内部,我试图在 rails 模型中包含一个模块

User.send :include, Something

这适用于第一个请求,但不适用于第二个/第三个/等。由于导轨模型重新加载。我尝试使用ActionDispatch::Callbacks.to_prepareActionDispatch::Callbacks.to_prepare,我使用的是 Rails 3.0.9)

ActionDispatch::Callbacks.to_prepare do
  User.send :include, Something
end

但是当我尝试在第二个/第三个/等上调用我的模块模块中定义的方法时,我不断从用户实例中收到 NoMethod 错误。要求。

我的问题是:有没有办法在初始化程序中可靠地将模块包含到 Rails 模型中而没有任何开发怪异?

更新:不可能

显然,如果没有中间件,这是不可能的。如果您不同意,请在下面添加答案。对于我的用例来说,这不是一个可接受的解决方案,所以我实际上什至没有尝试过。祝你好运。

编辑:更新的调试信息

我正在玩ActionDispatch::Callbacks.to_prepare更多的东西,当我把它放在我的初始化程序中时我发现了一些奇怪的东西:

ActionDispatch::Callbacks.to_prepare do
  puts "to_prepare ==:#{User.object_id}"
end

这在我的控制器中

puts "controller ==:#{User.object_id}"

在第一个请求我得到这个:

to_prepare ==: 2297196200
controller ==: 2297196200
to_prepare ==: 2297196200
to_prepare ==: 2324202920
to_prepare ==: 2318560780

在第二个请求我得到这个:

to_prepare ==: 2326823900
controller ==: 2326823900
to_prepare ==: 2317901920
to_prepare ==: 2326746040
to_prepare ==: 2314369160

我注意到的第一件事是对 to_prepare 的多次调用,这很奇怪。我注意到的第二件事是在第一个请求(有效)中,直接调用控制器之前和之后的 object_id 是相同的,并且它们不在任何后续调用中。如果有人能阐明为什么会发生这种情况以及如何解决它,将不胜感激。

4

1 回答 1

1

使用config.after_initialize钩子有帮助吗?由于发生了类重新加载,这是一个特定于开发环境的问题。

几乎可以肯定的一件事是通过中间件注入您的模块,尽管很难知道这是否适合您正在做的任何事情。

class AddYourModuleMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    User.send(:include, YourModule) unless User < YourModule
    @app.call(env)
  end
end

使用 将其添加到中间件链中config.middleware.use AddYourModuleMiddleware,或者将其use AddYourMiddleware放在ApplicationController.

于 2011-10-12T22:47:43.453 回答