ruby-on-rails ruby encapsulation helpers railstutorial.org

ruby on rails - SessionsHelper en railstutorial.org: ¿Los ayudantes deben ser módulos de propósito general para el código que no se necesitan en las vistas?



ruby-on-rails encapsulation (4)

De hecho, tu sentimiento es correcto.

Lo implementaría al revés: agregue las funciones sign_in y current_user a ApplicationController (o si realmente desea: en un módulo separado definido en lib e lib ), y luego asegúrese de que el método current_user esté disponible en la vista .

En breve:

class ApplicationController helper_method :current_user def sign_in end def current_user @current_user ||= user_from_remember_token end end

Por supuesto, si tiene mucho código para colocar en su ApplicationController , puede ensuciarse. En ese caso yo crearía un archivo lib/session_management.rb :

module SessionManagement def self.included(base) base.helper_method :current_user end def sign_in .. end def current_user .. end end

y dentro de tu controlador puedes escribir:

class ApplicationController include SessionManagement end

railstutorial.org tiene una sugerencia que me parece un poco rara.

Sugiere este código :

class ApplicationController < ActionController::Base protect_from_forgery include SessionsHelper end

La include SessionsHelper hace que los métodos estén disponibles desde ApplicationController , sí, pero también los hace disponibles en cualquier vista. Entiendo que la autenticación / autorización es transversal, pero ¿es este realmente el mejor lugar?

Eso me parece potencialmente un alcance demasiado amplio. El código que implementa, por ejemplo, un before_filter que redirecciona condicionalmente (como lo hace el ejemplo railstutorial.org) en un módulo que más comúnmente contiene ayudantes de vista parece sorprendente.

¿La funcionalidad que no se necesita estrictamente en las vistas se ubicaría mejor en ApplicationController o en otro lugar?

¿O simplemente estoy pensando demasiado en esto?


Esta es una pregunta filosófica en el mismo nivel que el argumento que cuestiona el método REST proporcionado en los andamios y si vale la pena tener un andamio. Debe tener en cuenta el hecho de que el libro de tutoriales en RailsTutorial.org es una guía instructiva de cómo ponerse en marcha Rails. Así que para el propósito que sirve, creo que hace el trabajo.

Sin embargo, ¿existe un lugar mejor para colocar el código necesario entre los controladores y las vistas? Sí hay.

  • Algunos pueden seguir el formulario de Railstutorial de Michael Hartl e incluir el SessionHelper completo en el ApplicationController
  • Otros pueden decidir exponer solo los ayudantes esenciales necesarios para la vista, es decir, sign_out , sign_out , current_user y similares.
  • Veo una sugerencia para poner dicho código en el directorio /lib e incluirlo donde sea necesario.

Todas son opciones viables. Lo que tome no importa mucho en el rendimiento, ya que Ruby tendría que analizar el archivo del que desea llamar (o incluir) una clase, un módulo o un método. Lo que sucede es que, antes de que se ejecute cualquier código en una clase, Ruby recorre toda la clase una vez para saber qué contiene. Todo depende de lo que uno necesite y del diseño de su aplicación.


FWIW, almaceno el usuario actual en la clase de Usuario:

class User < ActiveRecord::Base cattr_accessor :current ... end

Esto puede ser referenciado en los 3 niveles MVC; se establece en el controlador como tal (y también al iniciar sesión, por supuesto):

def set_current_user User.current = (session[:user_id]) ? User.find_by_id(session[:user_id]) : nil end

Entre otras cosas, esto me permite tener registros de auditoría en el nivel ActiveRecord que capturan al usuario actual (cuando corresponda).


Parece que se están aprovechando (furtivamente) del hecho de que, en Rails, los Helpers son solo módulos ruby.

Colocar el comportamiento que se comparte entre los Controladores en un Módulo es, en mi opinión, una buena práctica. Ponerlo en un Ayudante, por otro lado, es potencialmente engañoso y lo evitaría. Colóquelo en un módulo "estándar".