1

Railsの初期化子の内部で、モジュールをRailsモデルに含めようとしています

User.send :include, Something

これは最初のリクエストでは機能しますが、2 番目、3 番目などでは機能しません。Rails モデルのリロードが原因です。使ってみましたActionDispatch::Callbacks.to_prepare( ActionDispatch::Callbacks.to_prepare、Rails 3.0.9を使用しています)

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

しかし、2番目/3番目などのモジュールモジュールで定義されたメソッドを呼び出そうとすると、ユーザーインスタンスから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

2番目のリクエストで私はこれを取得します:

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

私が最初に気付いたのは、奇妙な to_prepare への複数の呼び出しです。私が気づいた 2 番目のことは、最初の要求 (これは機能します) で、コントローラーが呼び出される直前と直後の object_id は同じであり、その後の呼び出しには含まれていません。なぜこれが起こっているのか、そしてそれを回避する方法について誰かが光を当てることができれば、それは大歓迎です.

4

1 に答える 1

1

config.after_initializeフックの使用は役に立ちますか? これは、クラスのリロードが発生するため、開発環境固有の問題です。

ほぼ確実に機能することの 1 つは、ミドルウェアを介してモジュールを注入することですが、それが何をしていても適切な解決策であるかどうかを知ることは困難です。

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 に答える