为啥所有的 Rails 助手总是对所有视图可用?有没有办法禁用它?

Posted

技术标签:

【中文标题】为啥所有的 Rails 助手总是对所有视图可用?有没有办法禁用它?【英文标题】:Why are all Rails helpers available to all views, all the time? Is there a way to disable this?为什么所有的 Rails 助手总是对所有视图可用?有没有办法禁用它? 【发布时间】:2010-11-13 20:55:19 【问题描述】:

为什么我可以在另一个控制器的视图中访问一个控制器的辅助方法?有没有办法在不破解/修补 Rails 的情况下禁用它?

【问题讨论】:

有一个新的、更相关的答案。查看 Craig Walkers 的回答 【参考方案1】:

@George Schreiber 的方法在 Rails 3.1 中不起作用;代码发生了重大变化。

但是,现在在 Rails 3.1 中(希望以后)有更好的方法来禁用此功能。在您的 config/application.rb 中,添加以下行:

config.action_controller.include_all_helpers = false

这将是prevent ApplicationController from loading all of the helpers。

(有兴趣的朋友,here's the pull request where the feature was created。)

【讨论】:

我在 3.2。这里的application.config是指config/application.rb吗? 如果我禁用 include_all_helpers 或者我需要手动包含它,ApplicationHelper 是否也会被包含在内? @AzizLight 我不确定,因为我没有测试过。但是,我希望如此,因为 ApplicationHelper 旨在始终作为“根”助手在视图中可用。这里的主要问题是来自无关控制器的助手。 我认为这应该是默认行为。【参考方案2】:

答案取决于 Rails 版本。

导轨 >= 3.1

在要应用配置的任何环境中,将 include_all_helpers 配置更改为 false。如果您希望配置适用于所有环境,请在application.rb 中进行更改。

config.action_controller.include_all_helpers = false

如果为假,则为skip the inclusion。

导轨

ApplicationController中删除以下行

helper :all

这样每个控制器都会加载自己的帮助器。

【讨论】:

这行在 Rails 3.2 中对我来说不存在,所以这个解决方案可能不再适用于更高版本的 Rails。 我很想知道为什么这与 Rails 3.1 版本相比发生了如此显着的变化?对我来说没有多大意义。 注意:上述 cmets 不再有效,现在答案已更新为包含 Rails > 3.1 注意:您的 ApplicationHelper 仍将被加载。如果您想始终包含任何特定的帮助程序,您可以将 include HelperName 添加到 ApplicationHelper 的顶部。 适用于 Rails 4.1,仍然需要。为什么不是这个默认值......最好只在需要的地方包含特定的 Helpers(正如@vansan 所说)【参考方案3】:

在 Rails 3 中,actioncontroller/base.rb(第 224 行附近):

def self.inherited(klass)
  super
  klass.helper :all if klass.superclass == ActionController::Base
end

所以是的,如果你从ActionController::Base 派生你的类,所有的助手都会被包括进来。

要解决此问题,请在控制器代码的开头调用clear_helpersAbstractClass::Helpers;包含在ActionController::Base)。 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 时,(性能)损害已经造成,因为所有助手都已加载。你真的很想使用config.action_controller.include_all_helpers = false(正如上面的@Craig Walker所说),因为它首先阻止了助手被加载,从而为你获得了一些性能(也许在开发模式下最重要)。感谢您加入actioncontroller/base.rb sn-p;看到代码并消除一些谜团总是很高兴。 clear_helpers 仍然适用于 rails 3.0 - config.action_controller.include_all_helpers = false 仅适用于 rails 3.1 及更高版本。【参考方案4】:

实际上在 Rails 2 中,ActionController::Base 的默认功能是包含所有助手。

Changeset 6222 on 02/24/07 20:33:47 (3 years ago) by dhh: 将其作为默认假设,即您始终需要所有帮助者(是的,是的)

更改:

class ApplicationController < ActionController::Base 
  helper :all # include all helpers, all the time 
end 

从 Rails 3 beta 1 开始,CHANGELOG 中已不再是这种情况:

添加了 ActionController::Base 现在执行 helper :all 而不是依赖 Rails 中的默认 ApplicationController 执行此操作 [DHH]

【讨论】:

这是否意味着在 Rails 3 中,默认情况下所有帮助程序都是加载的? @Nik 肯定是的,至少 3.2

以上是关于为啥所有的 Rails 助手总是对所有视图可用?有没有办法禁用它?的主要内容,如果未能解决你的问题,请参考以下文章

在哪里放置不是模型、视图、控制器或助手的 Rails 代码?

为啥我的实例变量在我的 Rails 视图中总是 Nil

应用程序助手方法是不是适用于所有视图?

在 Rails 3 中使用助手输出 html

如何将 Rails 视图助手提取到 gem 中?

Ruby on Rails 使用视图助手中的变量在视图中动态生成字段名称