首页 > 解决方案 > 在rails中重定向循环

问题描述

email我的用户通过提供一个、一个account_type和一个在根 url 上注册password。他们收到一封要求确认的电子邮件。一旦他们确认了他们的电子邮件,他们就可以登录。但在他们可以使用任何网站功能之前,我希望他们通过提供username并设置一个 Stripe 帐户来完成他们的个人资料。我最初的想法是before_actionApplicationController. 就像:

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

为什么它会转到该页面然后再次重定向到该页面?

标签: ruby-on-railsdevise

解决方案


该方法似乎是正确的。但是,如果原始请求指向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操作!


推荐阅读