Подход, кажется, правильный. Однако использование текущего подхода приведет к циклу перенаправления, если исходный запрос направлен на users_onboard_path
.
Чтобы избежать цикла, вам нужно будет пропустить вызов current_user_has_complete_profile_and_stripe_account
before_action, когда исходный запрос направлен на действие users/onboard
. Для этого вы можете добавить следующую строку в 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
, и, следовательно, удаляем цикл.
UPDATE:
Я попытаюсь проиллюстрировать это с помощью созданного мной тестового приложения:
Файл 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
, и это становится циклом.
Однако, если мы добавим 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)
Как видно из журнала, входящий вызов перенаправляет на борт, но здесь перенаправление before_action
пропускается, и мы получаем ответ по желанию.
Точно так же и в вашем примере первый вызов перенаправляется на onboard
, а затем последующие вызовы также продолжают перенаправляться, потому что обратный вызов before_action
работает и для действия onboard
!