2011-06-22 23 views
5

Tengo problemas para entender la implementación de "Recordarme" en el Tutorial de Ruby on Rails de Michael Hartl. Se crea un módulo SessionsHelper con métodos para iniciar sesión, que contiene lo siguiente:Rieles: capacidad para "recordarme"

module SessionsHelper 

    def sign_in(user) 
     cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
     current_user = user 
    end 

    def current_user=(user) 
     @current_user = user 
    end 

    def current_user 
     return @current_user ||= user_from_remember_token 
    end 

    private 
     def user_from_remember_token 
      #passes array of length two as a parameter -- first slot contains ID, 
      #second contains SALT for encryption 
      User.authenticate_with_salt(*remember_token) 
     end 

     def remember_token 
      #ensures return of a double array in the event that 
      #cookies.signed[:remember_token] is nil. 
      cookies.signed[:remember_token] || [nil,nil] 
     end 

end 

NOTA: Elauthenticate_with_saltmétodo en el modelo de Usuario encuentra el usuario por el primer parámetro (el id) y si el usuario es definido y su sal es equivalente al segundo parámetro (la sal), luego se devuelve al usuario, de lo contrario, se devuelve nil.

Estoy teniendo problemas para entender por qué vamos a tales extremos para probar si el usuario ya ha sido firmado en:

En el caso de que el usuario ha iniciado sesión, @current_user ya está definido por el método sign_in y por lo tanto, el || = en el método current_user no tiene sentido.

En el caso de que el usuario no ha iniciado sesión, el || = operador en el método current_user devuelve el valor devuelto por el método user_from_remember_token, pero desde cookies.signed [: remember_token] sería nulo, User.authenticate_with_salt habría ser pasado el argumento [nil, nil] y devolvería nil, y por lo tanto, el método current_user devolvería nil.

En resumen, si el método current_user está volviendo @current_user si se define y nil de lo contrario, no sería mucho más sencillo de usar sólo el método de acceso convencional:

def current_user 
    return @current_user 
end 

libro de Michael Hartl dice que Hacer esto sería inútil porque el estado de inicio de sesión del usuario sería olvidado. ¿Por qué sería ese el caso? ¿Puede alguien explicar por qué no hacemos esto y en su lugar utilizar la versión mucho más compleja publicada anteriormente?

Respuesta

2

La línea

return @current_user ||= user_from_remember_token 

es una forma de inicialización perezosa para evitar la inicialización de la variable de @current_user hasta que realmente se necesita. @current_user nunca se inicializará la primera vez que se llame a esta función, pero tendrá un valor en cada llamada sucesiva (suponiendo que user_from_remember_token devuelva algo distinto de cero).

Él pudo haber escrito

def current_user 
    return user_from_remember_token 
end 

Este código será siempre inicializar el usuario actual a lo que se lee de la cookie. Esto se comportaría correctamente, pero probablemente quería evitar leer repetidamente la cookie, por lo que lo hace una vez y la almacena en una variable.

Él no puede hacer

def current_user 
    return @current_user 
end 

porque la variable @current_user no persiste a través de solicitudes de página. Una vez que la página se procesa y se envía de vuelta al cliente, la variable @current_user se destruye y se olvida su valor.

Espero que esto ayude. Consulte cómo mantener el estado en las aplicaciones web para obtener más información sobre por qué es necesario pasar por estos aros.

2

sign_in solo se invoca cuando inicia sesión con el formulario de inicio de sesión. Después de eso, debe configurar el usuario actual utilizando los valores de las cookies para cada solicitud.

Así, cuando el usuario ha iniciado sesión y abre una página, por primera vez current_user se llama rellenará la variable @current_user instancia y utilizarlo para otras current_user llamadas.

+0

Pero una vez que @current_user está configurado por sign_in, ¿no está allí para quedarse? ¿Por qué no podemos simplemente usar una variable de instancia @current_user en lugar de una cookie? ¿Cuál es la principal diferencia entre ellos? – Kvass

+0

Como la respuesta de Michael Venable dice: "la variable @current_user no persiste en todas las solicitudes de página". Así que, la primera vez que utiliza el método 'current_user' en una solicitud de página, debe obtener la información del usuario de la cookie. – vesan

Cuestiones relacionadas