Rails 6、允许用户通过验证后转到期望的页面
Rails 6, allow user to go to expected page after authentication
当用户登录 Devise 时,根据 after_sign_in_path_for() 方法进入 new_car_path。但是,在某些情况下,用户会尝试转到需要进行身份验证的特定页面。
我的示例,注销用户直接进入“域。com/compliance-form”,此页面要求用户在访问之前进行身份验证,因此正如预期的那样,它重定向到登录表单。当用户登录时,它会将他们带到“after_sign_in_path_for”路径,在本例中是“new_car_path”。
但是,由于用户确切地知道他们想去的页面,我希望他们去“compliance_form_path”“域。com/compliance-form”。
我该如何完成?
def after_sign_in_path_for(_resource=nil)
new_car_path
end
如果我添加stored_location_for(resource)
as user11350468 推荐:
def after_sign_in_path_for(resource = nil)
stored_location_for(resource) || new_car_path
end
我收到以下错误,
NoMethodError in SessionsController#create undefined method
`user_url' for #SessionsController:0x00007fc9f9bd1148 Did you mean?
search_url
然后添加:
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
即使在控制器中添加了 before action 之后,我仍然得到同样的错误,这是日志..
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"=>"name@domain.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Continue"}
User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = LIMIT [["email", "name@domain.com"], ["LIMIT", 1]]
↳ app/controllers/sessions_controller.rb:6:in `create'
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = ORDER BY "users"."id" ASC LIMIT [["email", "name@domain.com"], ["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" = , "last_sign_in_at" = , "sign_in_count" = , "updated_at" = WHERE "users"."id" = [["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 #<SessionsController:0x00007fae28d6a438>
Did you mean? search_url):
app/controllers/sessions_controller.rb:11:in `create'
更新:
我的语法有点不对,我应该发布准确的代码(吸取教训):
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
当 stored_location_for(resource)
被调用时,它变成了 nil
,因此 If
语句 returns true
,但是 stored_location_for(资源)值returnsnil
.
因此导致错误。 Stored_location_for() 下面的解决方案非常有效!
使用助手 stored_location_for
尝试以下操作
Returns and delete (if it's navigational format) the url stored in
the session for
the given scope. Useful for giving redirect backs after sign up:
根据设计 wiki,请在您的 application_controller 中添加以下 before_action
:
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
然后在 after_sign_in_path_for:
def after_sign_in_path_for(resource = nil)
stored_location_for(resource) || new_car_path
end
当用户登录 Devise 时,根据 after_sign_in_path_for() 方法进入 new_car_path。但是,在某些情况下,用户会尝试转到需要进行身份验证的特定页面。
我的示例,注销用户直接进入“域。com/compliance-form”,此页面要求用户在访问之前进行身份验证,因此正如预期的那样,它重定向到登录表单。当用户登录时,它会将他们带到“after_sign_in_path_for”路径,在本例中是“new_car_path”。
但是,由于用户确切地知道他们想去的页面,我希望他们去“compliance_form_path”“域。com/compliance-form”。
我该如何完成?
def after_sign_in_path_for(_resource=nil)
new_car_path
end
如果我添加stored_location_for(resource)
as user11350468 推荐:
def after_sign_in_path_for(resource = nil)
stored_location_for(resource) || new_car_path
end
我收到以下错误,
NoMethodError in SessionsController#create undefined method `user_url' for #SessionsController:0x00007fc9f9bd1148 Did you mean? search_url
然后添加:
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
即使在控制器中添加了 before action 之后,我仍然得到同样的错误,这是日志..
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"=>"name@domain.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Continue"}
User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."email" = LIMIT [["email", "name@domain.com"], ["LIMIT", 1]]
↳ app/controllers/sessions_controller.rb:6:in `create'
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = ORDER BY "users"."id" ASC LIMIT [["email", "name@domain.com"], ["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" = , "last_sign_in_at" = , "sign_in_count" = , "updated_at" = WHERE "users"."id" = [["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 #<SessionsController:0x00007fae28d6a438>
Did you mean? search_url):
app/controllers/sessions_controller.rb:11:in `create'
更新:
我的语法有点不对,我应该发布准确的代码(吸取教训):
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
当 stored_location_for(resource)
被调用时,它变成了 nil
,因此 If
语句 returns true
,但是 stored_location_for(资源)值returnsnil
.
因此导致错误。 Stored_location_for() 下面的解决方案非常有效!
使用助手 stored_location_for
Returns and delete (if it's navigational format) the url stored in the session for the given scope. Useful for giving redirect backs after sign up:
根据设计 wiki,请在您的 application_controller 中添加以下 before_action
:
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
然后在 after_sign_in_path_for:
def after_sign_in_path_for(resource = nil)
stored_location_for(resource) || new_car_path
end