为什么所有的Rails辅助方法都可以在所有视图中随时使用?有没有办法禁用这个功能?
Rails提供了许多helper方法,这些方法可以在所有的视图中使用。但是有些情况下,我们可能希望禁用某些helper方法,只在特定的视图中使用。那么为什么Rails中的所有helper方法都可以在所有的视图中使用呢?有没有办法禁用这个功能呢?
这个问题的答案取决于Rails的版本。
对于Rails >= 3.1的版本,可以通过改变include_all_helpers
配置来禁用这个功能。在任何需要应用这个配置的环境中,将include_all_helpers
设置为false
。如果想要在所有环境中应用这个配置,可以在application.rb
中进行修改。
config.action_controller.include_all_helpers = false
当include_all_helpers
设置为false时,Rails会跳过加载所有helper方法的步骤。
对于Rails < 3.1的版本,可以在ApplicationController
中删除以下代码:
helper :all
这样每个控制器将只加载自己的helper方法。
但是需要注意的是,这个解决方法可能不适用于Rails的后续版本,因为在Rails 3.2中,我找不到这行代码。
关于为什么从Rails 3.1版本开始发生了如此大的变化,我很感兴趣。对我来说,这个改变并没有太多意义。
值得注意的是,上面的评论已经过时,因为答案已经更新,适用于Rails > 3.1的版本。
需要注意的是,ApplicationHelper仍然会被加载。如果希望在所有视图中始终包含某些特定的helper方法,可以在ApplicationHelper的顶部添加include HelperName
。
在Rails 4.1中仍然需要使用这个解决方法。为什么这不是默认设置呢?最好的做法是只在需要时包含特定的helper方法。
在Rails 3中,actioncontroller/base.rb
文件中的代码(大约在第224行)是这样的:
def self.inherited(klass) super klass.helper :all if klass.superclass == ActionController::Base end
所以,如果你从ActionController::Base
派生你的类,所有的helpers都会被包含进来。
要解决这个问题,可以在控制器代码的开头调用clear_helpers
方法(该方法包含在ActionController::Base
中的AbstractClass::Helpers
模块中)。clear_helpers
的源代码注释如下:
# Clears up all existing helpers in this class, only keeping the helper # with the same name as this class.
例如:
class ApplicationController < ActionController::Base clear_helpers ... end
当你调用clear_helpers
时,(性能)损坏已经发生了,因为所有的helpers都已经被加载了。你真的想使用config.action_controller.include_all_helpers = false
(如上所述,Walker),因为它可以防止helpers被加载,从而提高性能(尤其是在开发模式下)。感谢你包含了actioncontroller/base.rb
的片段;看到代码可以消除一些神秘感。
clear_helpers
在Rails 3.0中仍然有用,而config.action_controller.include_all_helpers = false
只在Rails 3.1及以上版本中可用。
为什么所有的Rails辅助程序在所有视图中都是可用的?有没有办法禁用这个功能?
在Rails 3.1中,Schreiber的方法已经不起作用了,代码发生了重大变化。然而,在Rails 3.1(以及希望后续版本也适用)中,有一种更好的方法来禁用这个功能。在config/application.rb文件中添加以下代码:
config.action_controller.include_all_helpers = false
这将阻止ApplicationController加载所有的辅助程序。
(对于任何感兴趣的人,这是创建该功能的拉取请求的地址。)
我使用的是3.2版本。这里的application.config是指config/application.rb吗?
是的,这里的application.config指的是config/application.rb文件。
如果我禁用include_all_helpers,ApplicationHelper也会被包含吗?还是我需要手动包含它?
我不确定,因为我还没有进行过测试。然而,我认为应该包含ApplicationHelper,因为它被设计为在视图中始终可用的“根”辅助程序。这里主要问题是来自不相关控制器的辅助程序。
我认为这应该是默认行为。