¿Por qué todos los ayudantes de Rails están disponibles para todas las vistas, todo el tiempo? ¿Hay alguna forma de desactivar esto?

89

¿Por qué puedo acceder a los métodos auxiliares para un controlador en las vistas de un controlador diferente? ¿Hay alguna forma de desactivar esto sin hackear / parchear Rails?

Nate Smith
fuente
3
Hay una respuesta nueva y más relevante. Consulte la respuesta de Craig Walkers
EE33

Respuestas:

106

El método de @George Schreiber no funciona a partir de Rails 3.1; el código ha cambiado significativamente.

Sin embargo, ahora hay una manera aún mejor de desactivar esta función en Rails 3.1 (y con suerte más adelante). En su config / application.rb, agregue esta línea:

config.action_controller.include_all_helpers = false

Esto evitará que ApplicationController cargue todos los ayudantes .

(Para cualquiera que esté interesado, aquí está la solicitud de extracción donde se creó la función ).

Craig Walker
fuente
Estoy en 3.2. ¿Application.config aquí significa config / application.rb?
Brandon Henry
¿Se incluirá ApplicationHelper también si deshabilito include_all_helpers o si necesito incluirlo manualmente?
Robert Audi
@AzizLight No estoy seguro, ya que no lo he probado. Sin embargo, lo esperaría, ya que ApplicationHelper está destinado a estar siempre disponible en las vistas como ayudante "raíz". Son los ayudantes de controladores no relacionados los que son el problema principal aquí.
Craig Walker
3
Creo que este debería ser el comportamiento predeterminado.
Nafaa Boutefer
98

La respuesta depende de la versión de Rails.

Rieles> = 3,1

Cambie la include_all_helpersconfiguración a falseen cualquier entorno donde desee aplicar la configuración. Si desea que la configuración se aplique a todos los entornos, cámbiela application.rb.

config.action_controller.include_all_helpers = false

Cuando es falso, omitirá la inclusión .

Rieles <3,1

Elimine la siguiente línea de ApplicationController

helper :all

De esta forma, cada controlador cargará sus propios ayudantes.

Simone Carletti
fuente
2
Esta línea no existe para mí en Rails 3.2, por lo que es probable que esta solución ya no se aplique a versiones posteriores de Rails.
Tyler Collier
¡Lo que dijo @TylerCollier!
EE33
Me interesaría saber por qué esto cambió tan significativamente desde Rails hasta la versión 3.1. No tiene mucho sentido para mí.
Joshua Muheim
6
NOTA: Los comentarios anteriores ya no son válidos, ahora que la respuesta se ha actualizado para incluir Rails> 3.1
Kyle Heironimus
3
Nota: su ApplicationHelper se seguirá cargando. Si desea incluir ayudantes específicos todo el tiempo, puede agregarlos include HelperNamea la parte superior de su ApplicationHelper.
vansan
27

En Rails 3, actioncontroller/base.rb(alrededor de la línea 224):

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

Entonces sí, si deriva su clase de ActionController::Base, se incluirán todos los ayudantes.

Para solucionar esto, llame a clear_helpers( AbstractClass::Helpers; incluido en ActionController::Base) al comienzo del código de su controlador. Comentario del código fuente para clear_helpers:

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

P.ej:

class ApplicationController < ActionController::Base
  clear_helpers
  ...
end
George Schreiber
fuente
10
En el momento en que llame, clear_helpersel daño (de rendimiento) ya se ha hecho ya que todos los ayudantes se han cargado. Realmente desea usar config.action_controller.include_all_helpers = false(como indica @Craig Walker, arriba), ya que evita que los ayudantes se carguen en primer lugar, lo que le brinda algo de rendimiento (quizás lo más significativo en el modo de desarrollo). Gracias por incluir el actioncontroller/base.rbfragmento; Siempre es bueno ver el código y eliminar parte del misterio.
George Anderson
clear_helperssigue siendo útil para rails 3.0, config.action_controller.include_all_helpers = falsesolo es rails 3.1 y superior.
robd
5

En realidad, en Rails 2 , la funcionalidad predeterminada de ActionController :: Base era incluir todos los ayudantes.

Changeset 6222 el 24/02/07 20:33:47 (hace 3 años) por dhh : defecto que quiere todos los ayudantes, todo el tiempo (sí, sí)

cambio:

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

A partir de Rails 3 beta 1, ese ya no es el caso como se indica en el CHANGELOG:

  • Se agregó que ActionController :: Base ahora ayuda: todo en lugar de depender del ApplicationController predeterminado en Rails para hacerlo [DHH]
databyte
fuente
1
Entonces, ¿eso significa que en Rails 3, todos los ayudantes están cargados todo el tiempo por defecto?
Nik So
@Nik seguramente sí, al menos por 3.2
Nithin