我有两个相互引用的部分。当我在控制台中计算嵌套依赖项时(使用一些调试代码输出正在加载的模板):
finder = ApplicationController.new.lookup_context
ActionView::Digestor.new(name: "posts/show", finder: finder).nested_dependencies
或通过像这样的 rake 任务:
rake cache_digests:nested_dependencies TEMPLATE=posts/show
我得到一个初始依赖项的简短列表,然后在一个无限循环中,直到 ruby 堆栈已满:
...
>>>>>>> users/foo
>>>>>>> users/bar
>>>>>>> users/baz
>>>>>>> users/bip
>>>>>>> users/foo
>>>>>>> users/bar
>>>>>>> users/baz
>>>>>>> users/bip
SystemStackError: stack level too deep
(模板名称已更改)
但是,当我运行应用服务器并请求模板时,一切运行良好,没有无限循环。
以下是我在上述所有情况下的设置:
config.action_controller.perform_caching = true
config.cache_store = :file_store, Rails.root.to_s + '/tmp/cache/stuff'
ActionView::Base.cache_template_loading = true
该代码表明它确实具有递归引用保护:https ://github.com/rails/rails/blob/v4.1.8/actionview/lib/action_view/digestor.rb#L35
为什么这种保护在服务器环境中有效,但在控制台或 rake 任务中无效?
(也是一个 github 问题https://github.com/rails/rails/issues/18667)