我正在构建一个应用程序,该应用程序具有位于APP / sites / my_engine /的可安装但未隔离的rails引擎。我对使用此设置的典型请求的理解如下所示:
假设路线在引擎的路线中匹配并发送到页面#show action。将以下列优先级调用控制器:
如果你看看MyEngine :: Engine.paths ['app / controllers'],它是默认的[“app / controllers”] ..在这个上下文中是引擎。那么为什么它首先找到App的控制器呢?
控制器控制路径的优先级在哪里?
答案 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引擎版本永远不会被加载。