91

Why can I access helper methods for one controller in the views for a different controller? Is there a way to disable this without hacking/patching Rails?

Nate Smith
  • 1,103
  • 1
  • 15
  • 19

4 Answers4

107

@George Schreiber's method doesn't work as of Rails 3.1; the code has changed significantly.

However, there's now an even better way to disable this feature in Rails 3.1 (and hopefully later). In your config/application.rb, add this line:

config.action_controller.include_all_helpers = false

This will prevent ApplicationController from loading all of the helpers.

(For anyone who is interested, here's the pull request where the feature was created.)

Craig Walker
  • 49,871
  • 54
  • 152
  • 212
  • I'm on 3.2. Does application.config here mean config/application.rb? – Brandon Henry Nov 01 '12 at 18:34
  • Will the ApplicationHelper get included as well if I disable include_all_helpers or I need to include it manually? – Robert Audi Dec 01 '12 at 15:47
  • @AzizLight I'm not sure, since I haven't tested, that. However, I'd expect so, as ApplicationHelper is intended to be always be available in views as the "root" helper. It's the helpers from unrelated controllers that are of primary issue here. – Craig Walker Dec 01 '12 at 23:22
  • 3
    I think this should be the default behavior. – Nafaa Boutefer Dec 21 '14 at 22:12
99

The answer depends on the Rails version.

Rails >= 3.1

Change the include_all_helpers config to false in any environment where you want to apply the configuration. If you want the config to apply to all environments, change it in application.rb.

config.action_controller.include_all_helpers = false

When false, it will skip the inclusion.

Rails < 3.1

Delete the following line from ApplicationController

helper :all

In this way each controller will load its own helpers.

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • 2
    This line doesn't exist for me in Rails 3.2, so this solution likely no longer applies to later versions of Rails. – Tyler Collier Sep 25 '12 at 05:54
  • I'd be interested in why this changed so significantly from Rails up version 3.1? Doesn't make much sense to me. – Joshua Muheim Nov 21 '12 at 09:40
  • 6
    NOTE: The above comments are no longer valid, now that the answer has been updated to include Rails > 3.1 – Kyle Heironimus Dec 12 '12 at 22:16
  • 3
    Note: Your ApplicationHelper will still be loaded. If you'd like to include any specific helpers all of the time, you can add `include HelperName` to the top of your ApplicationHelper. – vansan Jan 15 '13 at 20:36
  • works for Rails 4.1, still needed. Why isn't this default ... it's better to include only particular Helpers where needed (as @vansan said) – Ondřej Želazko Aug 21 '14 at 13:13
27

In Rails 3, actioncontroller/base.rb (around line 224):

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

So yes, if you derive your class from ActionController::Base, all helpers will be included.

To come around this, call clear_helpers (AbstractClass::Helpers; included in ActionController::Base) at the beginning of your controller's code. Source code comment for clear_helpers:

# Clears up all existing helpers in this class, only keeping the helper
# with the same name as this class.

E.g.:

class ApplicationController < ActionController::Base
  clear_helpers
  ...
end
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
  • 10
    By the time you call `clear_helpers` the (performance) damage has already been done since all of the helpers have been loaded. You really want to use `config.action_controller.include_all_helpers = false` (as @Craig Walker states, above), as it prevents the helpers from being loaded in the first place, thus gaining you some performance (perhaps most significantly in development mode). Thanks for including the `actioncontroller/base.rb` snippet; it's always nice to see code and remove some of the mystery. – George Anderson Nov 12 '11 at 03:17
  • `clear_helpers` is still useful for rails 3.0 - `config.action_controller.include_all_helpers = false` is only rails 3.1 and above. – robd Mar 12 '14 at 16:06
5

Actually in Rails 2, the default functionality of ActionController::Base was to include all helpers.

Changeset 6222 on 02/24/07 20:33:47 (3 years ago) by dhh: Make it a default assumption that you want all helpers, all the time (yeah, yeah)

change:

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

As of Rails 3 beta 1, that is no longer the case as noted in the CHANGELOG:

  • Added that ActionController::Base now does helper :all instead of relying on the default ApplicationController in Rails to do it [DHH]
databyte
  • 1,228
  • 10
  • 7