控制器路径的优先级在哪里可安装但不是隔离的Rails :: Engine?

时间:2013-03-31 00:31:43

标签: ruby-on-rails-3

我正在构建一个应用程序,该应用程序具有位于APP / sites / my_engine /的可安装但未隔离的rails引擎。我对使用此设置的典型请求的理解如下所示:

  1. 请求通过主应用程序的中间件堆栈。
  2. 请求命中主应用程序的路由器,并匹配已安装的路径。它将已安装的部件放入:env [“SCRIPT_NAME”]并通过引擎发送请求。
  3. 请求通过Engine的中间件堆栈。
  4. 请求命中了引擎的路由器并匹配路由的剩余部分。
  5. 假设路线在引擎的路线中匹配并发送到页面#show action。将以下列优先级调用控制器:

    1. 如果PagesController与主应用程序中的show动作一起存在,它将首先调用它。
    2. 如果PagesController存在引擎中的show动作,只有当第一个不存在时才会调用此秒。
    3. 如果你看看MyEngine :: Engine.paths ['app / controllers'],它是默认的[“app / controllers”] ..在这个上下文中是引擎。那么为什么它首先找到App的控制器呢?

      控制器控制路径的优先级在哪里?

1 个答案:

答案 0 :(得分:0)

好的,所以这花了一些时间才弄明白。在生产模式下引导rails时会发生的情况是,在初始化rails运行结束时(参见Initialization Order):

Rails::Engine#eager_load! 

这里Rails通过以下方式获取所有eager_load_path:

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会在找到引擎版本之前找到该文件的App版本,并且如果它们共享相同的名称,则每次加载它。 rails引擎版本永远不会被加载。