Rails 6, permite al usuario ir a página esperada después de la autenticación
Cuando un usuario firma en Devise tomada a un nuevo_car_path por el método after_sign_in_path_for(). Sin embargo, hay situaciones en las que el Usuario tratará de ir a una página específica que necesita ser autenticada.
Mi ejemplo, el usuario registrado va directamente a "domain.com/cumplimiento-forma", esta página requiere que el usuario sea autenticado antes de alcanzarlo, así como se espera, se redirige a un signo en forma. Cuando el usuario se registra, los lleva al camino "after_sign_in_path_for", que en este cuidado es el "new_car_path".
Sin embargo, como el usuario sabe exactamente la página a la que quiere ir, quiero que vayan a "cumplir_form_path" "domain.com/cumplimiento-forma".
¿Cómo logro esto?
def after_sign_in_path_for(_resource=nil)
new_car_path
end
Si agrego stored_location_for(resource)
como usuario11350468 recomendado:
def after_sign_in_path_for(resource = nil)
stored_location_for(resource) || new_car_path
end
Tengo el siguiente error,
NoMethodError en SessionsController #crear método indefinido `user_url' para #SessionsController:0x00007fc9f9bd1148 ¿Te refieres? search_url
THen agregó:
class ApplicationController < ActionController::Base
before_action :store_user_location!, if: :storable_location?
def storable_location?
request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
end
def store_user_location!
store_location_for(:user, request.fullpath)
end
end
Incluso después de agregar antes de la acción en el controlador, tengo el mismo error, aquí están los registros..
Started GET "/compliance_form for 127.0.0.1 at 2020-12-17 11:26:14 -0600
Processing by ComplianceController#new as HTML
Completed 401 Unauthorized in 4ms (ActiveRecord: 0.0ms | Allocations: 411)
Started GET "/users/sign_in" for 127.0.0.1 at 2020-12-17 11:26:14 -0600
Processing by SessionsController#new as HTML
Rendering devise/sessions/new.html.erb within layouts/devise
Rendered devise/sessions/new.html.erb within layouts/devise (Duration: 20.3ms | Allocations: 9174)
Rendered layouts/_head.html.erb (Duration: 361.5ms | Allocations: 235189)
Rendered layouts/_devise_navbar.html.erb (Duration: 3.7ms | Allocations: 901)
Rendered layouts/_footer.html.erb (Duration: 0.1ms | Allocations: 5)
Completed 200 OK in 399ms (Views: 395.8ms | ActiveRecord: 0.0ms | Allocations: 249472)
Started POST "/users/sign_in" for 127.0.0.1 at 2020-12-17 11:26:21 -0600
Processing by SessionsController#create as HTML
Parameters: {"authenticity_token"=>"IDqVSy1swedds22AEqMEzQQnamz7I+gysdfbNlPPhsRTMJGZkWCgWFYq1vg/3Af2Af5xjchnzdfgoH6m7wHXEA==", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Continue"}
User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "[email protected]"], ["LIMIT", 1]]
↳ app/controllers/sessions_controller.rb:6:in `create'
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "[email protected]"], ["LIMIT", 1]]
↳ app/controllers/sessions_controller.rb:11:in `create'
(0.6ms) BEGIN
↳ app/controllers/sessions_controller.rb:11:in `create'
User Update (1.0ms) UPDATE "users" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5 [["current_sign_in_at", "2020-12-17 17:26:21.278696"], ["last_sign_in_at", "2020-12-17 17:24:43.660819"], ["sign_in_count", 31], ["updated_at", "2020-12-17 17:26:21.279770"], ["id", 2]]
↳ app/controllers/sessions_controller.rb:11:in `create'
(4.6ms) COMMIT
↳ app/controllers/sessions_controller.rb:11:in `create'
Redirected to
Completed 500 Internal Server Error in 610ms (ActiveRecord: 9.9ms | Allocations: 188187)
NoMethodError (undefined method `user_url' for #
Did you mean? search_url):
app/controllers/sessions_controller.rb:11:in `create'
UPDATE:
Mi sintaxis estaba ligeramente apagada, debería haber publicado el código exacto (sin saber):
def after_sign_in_path_for(_resource=nil)
return stored_location_for(resource) if stored_location_for(resource).present?
return car_index_path if current_user.car?
new_car_path
end
Lo que está pasando es cuando stored_location_for(resource)
se llama, se convierte en nil
, y así el If
declaración devuelve true
, pero el valor almacenado_location_for(resource) devuelve nil
.
Por lo tanto, causando el error. Stored_location_for() solución abajo funciona genial!
Pregunta hecha hace 3 años, 4 meses, 28 días - Por scriptsculptor52b5
3 Respuestas:
-
Pruebe a continuación con ayudador
stored_location_for
Devuelve y elimina (si es formato de navegación) el url almacenado en del período de sesiones el alcance dado. Útil para dar espaldas redireccionables después de registrarse:
Según la idea wiki, por favor agregue el siguiente
before_action
en su aplicación_ controlador:class ApplicationController < ActionController::Base before_action :store_user_location!, if: :storable_location? def storable_location? request.get? && is_navigational_format? && !devise_controller? && !request.xhr? end def store_user_location! store_location_for(:user, request.fullpath) end end
Y luego en after_sign_in_path_for:
def after_sign_in_path_for(resource = nil) stored_location_for(resource) || new_car_path end
Respondida el Dec 17, 2020 a las 13:26 - por codecrafty
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a que en el método
after_sign_in_path_for
estás utilizandostored_location_for(resource)
sin definir previamenteresource
. Para solucionar esto puedes modificar tu método de la siguiente manera:ruby def after_sign_in_path_for(resource) stored_location = stored_location_for(resource) if stored_location stored_location else new_car_path end end
De esta forma, primero obtienes el valor almacenado en
stored_location_for(resource)
y luego verificas si existe algún valor almacenado. Si hay un valor almacenado, redireccionarás al usuario a esa ruta, de lo contrario lo redirigirás anew_car_path
.Además, en tu controlador de ApplicationController, puedes añadir la siguiente verificación para asegurarte de que el recurso esté definido antes de almacenar la ubicación:
ruby def storable_location? request.get? && is_navigational_format? && !devise_controller? && !request.xhr? && !current_user.nil? end
Esto garantizará que la ubicación solo se almacene cuando haya un usuario autenticado.
Con estas modificaciones, tu código debería funcionar correctamente y redirigir al usuario a la página esperada después de la autenticación.
Respondida el Dec 18, 2020 a las 13:26 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Problema:
Parece que estás intentando redirigir a los usuarios a una página específica después de que inicien sesión, pero te encuentras con un error porque el método
user_url
no está definido en el controladorSessionsController
.Solución:
Para resolver este problema, puedes utilizar el método
stored_location_for
proporcionado por Devise. Este método almacena la URL de la página a la que el usuario intentaba acceder antes de ser redirigido al formulario de inicio de sesión.Para usar
stored_location_for
, agrega el siguiente código a tu controladorSessionsController
en el métodoafter_sign_in_path_for
:def after_sign_in_path_for(_resource=nil) stored_location_for(resource) || new_car_path end
Este código verificará si hay una ubicación almacenada para el usuario y lo redirigirá a esa página. Si no hay una ubicación almacenada, lo redirigirá a
new_car_path
.Acción antes:
Además, para que el método
stored_location_for
funcione correctamente, debes agregar una acción antes al controladorApplicationController
para almacenar la ubicación actual:class ApplicationController < ActionController::Base before_action :store_user_location!, if: :storable_location? def storable_location? request.get? && is_navigational_format? && !devise_controller? && !request.xhr? end def store_user_location! store_location_for(:user, request.fullpath) end end
Esto almacenará la ubicación actual para el usuario en cada solicitud GET que no sea una solicitud de Devise o AJAX.
Ejemplo actualizado:
Tu código actualizado quedaría así:
SessionsController
class SessionsController < Devise::SessionsController def after_sign_in_path_for(_resource=nil) stored_location_for(resource) || new_car_path end end
ApplicationController
class ApplicationController < ActionController::Base before_action :store_user_location!, if: :storable_location? def storable_location? request.get? && is_navigational_format? && !devise_controller? && !request.xhr? end def store_user_location! store_location_for(:user, request.fullpath) end end
Con estos cambios, los usuarios ahora serán redirigidos a la página a la que intentaban acceder antes de iniciar sesión si esa página requiere autenticación.
Respondida el Dec 18, 2020 a las 13:30 - por Gemini
Votos positivos: 0 | Votos negativos: 0