Почему все помощники Rails всегда доступны для всех представлений? Есть ли способ отключить это?

89

Почему я могу получить доступ к вспомогательным методам для одного контроллера в представлениях для другого контроллера? Есть ли способ отключить это без взлома / исправления Rails?

Нейт Смит
источник
3
Есть новый, более актуальный ответ. Посмотрите ответ Крейга Уокерса
EE33,

Ответы:

106

Метод @George Schreiber не работает с Rails 3.1; код существенно изменился.

Однако теперь есть еще лучший способ отключить эту функцию в Rails 3.1 (и, надеюсь, позже). В вашем config / application.rb добавьте эту строку:

config.action_controller.include_all_helpers = false

Это предотвратит загрузку ApplicationController всех помощников .

(Для всех, кому интересно, вот пул реквест, в котором функция была создана .)

Крэйг Уокер
источник
Я на 3.2. Означает ли здесь application.config config / application.rb?
Брэндон Генри
Будет ли включен ApplicationHelper, если я отключу include_all_helpers или мне нужно будет включить его вручную?
Роберт Ауди,
@AzizLight Я не уверен, так как я не тестировал это. Однако я ожидал этого, поскольку ApplicationHelper всегда должен быть доступен в представлениях как «корневой» помощник. Основная проблема здесь - помощники от несвязанных контроллеров.
Крейг Уокер,
3
Я думаю, это должно быть поведение по умолчанию.
Nafaa Boutefer
98

Ответ зависит от версии Rails.

Рельсы> = 3.1

Измените include_all_helpersконфигурацию на falseлюбую среду, в которой вы хотите применить конфигурацию. Если вы хотите, чтобы конфигурация применялась ко всем средам, измените ее в application.rb.

config.action_controller.include_all_helpers = false

Если установлено значение false, включение будет пропущено .

Рельсы <3.1

Удалите следующую строку из ApplicationController

helper :all

Таким образом, каждый контроллер загрузит своих помощников.

Симоне Карлетти
источник
2
Эта строка не существует для меня в Rails 3.2, поэтому это решение, вероятно, больше не применимо к более поздним версиям Rails.
Тайлер Кольер
Что сказал @TylerCollier!
EE33,
Мне было бы интересно узнать, почему это так сильно изменилось по сравнению с Rails до версии 3.1? Для меня это не имеет особого смысла.
Джошуа Мухейм
6
ПРИМЕЧАНИЕ. Приведенные выше комментарии больше не действительны, теперь, когда ответ был обновлен и теперь включает Rails> 3.1
Kyle Heironimus
3
Примечание. Ваш ApplicationHelper по-прежнему будет загружен. Если вы хотите постоянно включать каких-либо конкретных помощников, вы можете добавить их include HelperNameв начало своего ApplicationHelper.
vansan
27

В Rails 3 actioncontroller/base.rb(около строки 224):

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

Так что да, если вы унаследовали свой класс от ActionController::Base, все помощники будут включены.

Чтобы обойти это, вызовите clear_helpers( AbstractClass::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
Джордж Шрайбер
источник
10
К тому времени, когда вы вызываете clear_helpers(производительность), ущерб уже был нанесен, поскольку все помощники были загружены. Вы действительно хотите использовать config.action_controller.include_all_helpers = false(как заявляет @Craig Walker выше), поскольку он в первую очередь предотвращает загрузку помощников, тем самым повышая производительность (возможно, наиболее существенно в режиме разработки). Благодарим за actioncontroller/base.rbдобавление фрагмента. Всегда приятно увидеть код и избавиться от тайны.
Джордж Андерсон
clear_helpersеще пригодится для рельсов 3.0 - config.action_controller.include_all_helpers = falseэто только рельсы 3.1 и выше.
robd
5

Фактически в Rails 2 функциональность ActionController :: Base по умолчанию должна была включать все помощники.

Набор изменений 6222 от 24.02.07 20:33:47 (3 года назад) от dhh : Сделайте предположение по умолчанию, что вам нужны все помощники все время (да, да)

изменение:

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

Что касается Rails 3 beta 1, это уже не так, как указано в CHANGELOG:

  • Добавлено, что ActionController :: Base теперь выполняет helper: all вместо того, чтобы полагаться на ApplicationController по умолчанию в Rails, чтобы делать это [DHH]
байт данных
источник
1
Значит ли это, что в Rails 3 все помощники по умолчанию загружаются постоянно?
Ник Со
@Nik конечно да, по крайней мере для 3.2
Nithin 04