0

APP/sites/my_engine/ にマウント可能だが分離されていない Rails エンジンを持つアプリケーションを構築しています。このセットアップでの典型的なリクエストについての私の理解は次のようになります。

  1. リクエストは、メイン アプリのミドルウェア スタックを通過します。
  2. リクエストはメイン アプリのルーターにヒットし、マウントされたパスと一致します。マウントされたパーツを env["SCRIPT_NAME"] に配置し、エンジンを介してリクエストを送信します。
  3. リクエストは、エンジンのミドルウェア スタックを通過します。
  4. リクエストはエンジンのルーターにヒットし、ルートの残りの部分と一致します。

ルートがエンジンのルートで一致し、pages#show アクションにディスパッチするとします。コントローラーは次の優先度で呼び出されます。

  1. メインアプリに show アクションを持つ PagesController が存在する場合、これが最初に呼び出されます。
  2. エンジンに show アクションを持つ PagesController が存在する場合、最初のコントローラが存在しなかった場合にのみ、この 2 番目のコントローラが呼び出されます。

MyEngine::Engine.paths['app/controllers'] を見ると、デフォルトの ["app/controllers"] です。このコンテキストではエンジンです。では、なぜ最初にアプリのコントローラーを見つけるのでしょうか?

コントローラのパスのこの優先順位はどこで制御されますか?

4

1 に答える 1

0

わかりましたので、これを理解するのに時間がかかりました。本番モードでレールを起動すると、初期化の終わりに向かってレールが実行されます (初期化順序を参照)。

Rails::Engine#eager_load! 

ここで、Rails は次の方法ですべてのeager_load_paths を取得します。

config.eager_load_paths

例えば:

[
  APP/controllers/pages_controller.rb, 
  APP/sites/my_engine/controllers/pages_controller.rb
]

各eager_load_pathに対してメソッドを呼び出します

ActiveSupport::Dependencies#require_dependency. 

require_dependency では、Rails は以下を呼び出します。

Dependencies#depend_on

これは、各パスをエンディング (つまり、「pages_controller」) だけに取り除き、次を呼び出します。

Dependencies#search_for_file

これにより .rb が追加されるため、「pages_controller.rb」が作成され、autoload_paths でファイルが検索されます。Rails パスは autoload_paths の最初にあるため、Rails はエンジン バージョンを見つける前にファイルのアプリ バージョンを見つけて、同じ名前を共有している場合は毎回それをロードします。Rails エンジンのバージョンが読み込まれることはありません。

于 2013-03-31T04:05:59.873 に答える