ruby-on-rails - 在rails中重定向循环
问题描述
email
我的用户通过提供一个、一个account_type
和一个在根 url 上注册password
。他们收到一封要求确认的电子邮件。一旦他们确认了他们的电子邮件,他们就可以登录。但在他们可以使用任何网站功能之前,我希望他们通过提供username
并设置一个 Stripe 帐户来完成他们的个人资料。我最初的想法是before_action
在ApplicationController
. 就像:
class ApplicationController < ActionController::Base
before_action :current_user_has_complete_profile_and_stripe_account
private
def current_user_has_complete_profile_and_stripe_account
if user_signed_in? && current_user.username.blank?
redirect_to users_onboard_path
end
end
end
但是,当我使用新批准的用户登录时,这会导致重定向循环。终端输出为:
Redirected to http://localhost:3000/users/onboard
Filter chain halted as :current_user_has_complete_profile_and_stripe_account rendered or redirected
为什么它会转到该页面然后再次重定向到该页面?
解决方案
该方法似乎是正确的。但是,如果原始请求指向users_onboard_path
.
为了避免循环,current_user_has_complete_profile_and_stripe_account
当原始请求被定向到users/onboard
操作时,您需要跳过 before_action 调用。为此,您可以users_controller.rb
在控制器类内部的顶部添加以下行(假设该文件包含onboard
操作):
skip_before_action :current_user_has_complete_profile_and_stripe_account, only: [:onboard]
通过这样做,我们基本上会跳过current_user_has_complete_profile_and_stripe_account
在执行动作之前调用的onboard
动作,因此,删除循环。
更新:
我将尝试借助我创建的测试应用程序来说明这一点:应用程序
的application_controller.rb
文件如下:
class ApplicationController < ActionController::Base
before_action :current_user_has_complete_profile_and_stripe_account
private
def current_user_has_complete_profile_and_stripe_account
p "I'm in the before_action call current_user_has_complete_profile_and_stripe_account"
if some_condition?
p "I'm redirecting to the onboard API"
redirect_to onboard_users_path
end
end
def some_condition?
true
end
end
在此文件中,我们定义了一个before_action
回调以重定向到入职路径。
这个应用程序的users_controller.rb
文件如下:
class UsersController < ApplicationController
def login
p "I'm in login"
render json: { message: "This is a message from login action" }
end
def onboard
p "I'm in onboard!"
render json: { message: "This is a message from onboard action" }
end
end
当我尝试访问登录 API 时,我遇到了一个重定向循环,如终端输出所示:
Started GET "/users/login" for ::1 at 2019-04-10 11:16:09 +0530
Processing by UsersController#login as */*
"I'm in the before_action call current_user_has_complete_profile_and_stripe_account"
"I'm redirecting to the onboard API"
Redirected to http://localhost:3001/users/onboard
Filter chain halted as :current_user_has_complete_profile_and_stripe_account rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
Started GET "/users/onboard" for ::1 at 2019-04-10 11:16:09 +0530
Processing by UsersController#onboard as */*
"I'm in the before_action call current_user_has_complete_profile_and_stripe_account"
"I'm redirecting to the onboard API"
Redirected to http://localhost:3001/users/onboard
Filter chain halted as :current_user_has_complete_profile_and_stripe_account rendered or redirected
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
基本上,我们before_action
首先在调用中点击登录方法,然后尝试重定向到onboard_users_path
. 但是,当调用/users/onboard
重定向时,我们再次点击该before_action
块,并且再次尝试将我们重定向到/users/onboard
,这变成了一个循环。
但是,如果我们将 a 添加skip_before_action :current_user_has_complete_profile_and_stripe_account, only: [:onboard]
到我们的users_controller.rb
中,我们会得到以下输出:
Started GET "/users/login" for ::1 at 2019-04-10 11:22:34 +0530
Processing by UsersController#login as */*
"I'm in the before_action call current_user_has_complete_profile_and_stripe_account"
"I'm redirecting to the onboard API"
Redirected to http://localhost:3001/users/onboard
Filter chain halted as :current_user_has_complete_profile_and_stripe_account rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.0ms)
Started GET "/users/onboard" for ::1 at 2019-04-10 11:22:34 +0530
Processing by UsersController#onboard as */*
"I'm in onboard!"
Completed 200 OK in 1ms (Views: 0.3ms | ActiveRecord: 0.0ms)
如日志中所见,登录调用重定向到 onboard,但在这里,before_action
重定向被跳过,我们得到了所需的响应。
同样,在您的示例中,第一个调用也重定向到onboard
,然后后续调用也不断被重定向,因为before_action
回调也运行以执行onboard
操作!
推荐阅读
- oracle - 在 Oracle APEX 中启用 SSO 登录
- html - 边距和高度值不同时渲染的 div 高度不同
- java - 日历对象接缝不要交给使用 Android 和 datepicker 的方法
- java - “java.lang”不包含 ObjectFactory.class 或 jaxb.index
- go - 如何在元帅中省略结构的条件字段
- java - 反应堆核心通量:FluxSink.OverflowStrategy 和 onBackPressure* 之间的区别?
- r - pickerInput 显示数值而不是字符
- django - 为外键字段赋值
- django - 在同一域下使用 Nginx 和 Gunicorn 为多个 Django 应用程序提供服务
- javascript - .show() 不能立即工作 - jQuery