ruby on rails 3 - rails - Diseñar y ubicación_de_almacenamiento_para: ¿cómo se almacena la ubicación de devolución?
devise redirect after sign in (5)
Tengo una página cuya ruta es (por ejemplo) / locales / 92 en la que estoy mostrando "por favor [iniciar sesión] o [registrar] para obtener información adicional" si el usuario no ha iniciado sesión, y quiero idear para devolver el mismo / local / 92 página después de que el usuario inicia sesión.
He leído otras publicaciones y creo que entiendo cómo se supone que la stored_location_for
funciona. En teoría, podría poner algo como esto en mi ApplicationController
:
def stored_location_for(resource)
if (r = session[:return_to])
session[:return_to] = nil
r
else
super
end
end
Mi pregunta es: ¿cómo / dónde configuro la sesión [: return_to]?
Quiero configurar la sesión [: return_to] solo si el usuario hace clic en [iniciar sesión] o [registrarse], pero ¿cuál es la mejor manera de hacerlo?
- Decorar los enlaces con JavaScript? Eso podría funcionar, pero parece ser torpe.
- Establecerlo en el controlador de las instalaciones antes de representar la página? Eso no parece correcto: ¿y si el usuario no hace clic en los enlaces [iniciar sesión] o [registrar]? Luego tengo la sesión [: return_to] configurada en algún valor impar que podría hacerme tropezar si el usuario inicia sesión desde alguna otra página.
- Agregue una cadena de consulta
?return_to=/premises/92
a los enlaces [log in] y [register], y detecte eso en el regulador de registros y el controlador de sesiones y use esa información para configurar la sesión [: return_to]? Parece que funcionaría, pero también con mano dura.
Ninguno de estos huele bien. ¿Cuál es la técnica generalmente aceptada para configurar el estado de ubicación_de_almacenamiento_para?
Diseñar uso
session["#{scope}_return_to"]
Entonces puede usar la session["user_return_to"]
si su modelo de autenticación es User.
Encontré todo este ingenio de redirección bastante confuso.
Donde @rorra dice que Devise usa la session["#{scope}_return_to"]
, quiere decir que Devise default after_sign_in_path_for(resource)
usará esa variable a través del método stored_location_for(resource)
.
Por lo tanto, debe guardar la ubicación que desea almacenar en la session["#{scope}_return_to"]
variable session["#{scope}_return_to"]
, que normalmente será la session["user_return_to"]
. Para hacer esto, coloque lo siguiente en su application_controller.rb:
after_action :store_location
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
if (request.fullpath != "/users/sign_in" &&
request.fullpath != "/users/sign_up" &&
request.fullpath != "/users/password" &&
request.fullpath != "/users/sign_out" &&
!request.xhr?) # don''t store ajax calls
session["user_return_to"] = request.fullpath
end
end
En algunos casos, no será necesario definir un after_sign_in_path_for(resource)
ya que el método predeterminado del after_sign_in_path_for(resource)
hará todos los redireccionamientos para usted y, si no hay una URL de redireccionamiento disponible, se lo redireccionará a la ruta raíz del recurso (generalmente la ruta raíz del usuario) y si eso no existe, se te redirigirá a la ruta raíz. Sin embargo, si desea personalizar el lugar donde se envía al usuario si no hay una URL de redireccionamiento disponible, agregue lo siguiente a su application_contorller.rb (y cambie root_path
consecuencia):
def after_sign_in_path_for(resource)
stored_location_for(resource) || root_path
end
Me gusta esto
class ApplicationController < AC::Base
after_filter :clear_attached_unit # UPDATED
protected
def clear_attached_unit
session[:attached_unit_path] = nil unless keep_attached_unit_path?
end
def keep_attached_unit_path? # UPDATED
@keep_attached_unit_path
end
end
class UnitController < ApplicationController
before_filter :attach_unit, :only => [:show]
protected
def attach_unit
session[:attached_unit_path] = request.url if request.get? && !request.xhr?
end
end
class SessionsController < Devise::SessionsController
before_filter :keep_attached_unit_path! # UPDATED
protected
def keep_attached_unit_path! # UPDATED
@keep_attached_unit_path = true
end
def after_sign_in_path_for(resource_or_scope)
if resource_or_scope.is_a?(User) && session[:attached_unit_path].present?
session[:attached_unit_path]
else
super
end
end
end
Y extrae esto al módulo.
aquí está lo mejor que pude encontrar. Funciona perfectamente también con la autenticación de Facebook. al agregar más restricciones a la adición de URL a la variable de sesión, puede eliminar más y más rutas que no desea que el usuario devuelva también (por ejemplo, devoluciones de llamada, páginas de inicio, páginas de inicio, etc.)
#ApplicationsController
after_filter :store_location
def store_location
session[:previous_urls] ||= []
# store unique urls only
session[:previous_urls].prepend request.fullpath if session[:previous_urls].first != request.fullpath && request.fullpath != "/user" && request.fullpath != "/user/login" && request.fullpath != "/" && request.fullpath != "/user/logout" && request.fullpath != "/user/join" && request.fullpath != "/user/auth/facebook/callback"
# For Rails < 3.2
# session[:previous_urls].unshift request.fullpath if session[:previous_urls].first != request.fullpath
session[:previous_urls].pop if session[:previous_urls].count > 3
end
def after_sign_in_path_for(resource)
@url = session[:previous_urls].reverse.first
if @url != nil
"http://www.google.com" + @url
else
root_path
end
end
Devise
busca la clave "#{resource}_return_to"
en la sesión.
Aquí estoy citando la API:
De forma predeterminada, primero intenta encontrar una clave
#{resource}_return_to
en la sesión, luego recurre a#{resource}_root_path
, de lo contrario utiliza laroot_path
.