петля перенаправления в рельсах - PullRequest
0 голосов
/ 31 марта 2019

Мои пользователи регистрируются в корневом URL-адресе, предоставляя email, account_type и 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

Почему происходит переход на эту страницу и затем повторное перенаправление на страницу?

Ответы [ 3 ]

2 голосов
/ 09 апреля 2019

Подход, кажется, правильный. Однако использование текущего подхода приведет к циклу перенаправления, если исходный запрос направлен на 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!

1 голос
/ 10 апреля 2019

Ваше приложение перенаправляет, потому что, когда вы нажимаете на вход в систему, условие users_signed_in? && current_user.username.blank? все еще выполняется.Поэтому один и тот же обратный вызов запускается, потому что все ваши контроллеры наследуются от ApplicationController, и вы в конечном итоге получаете цикл перенаправления.

Вы можете добавить проверку в обратном вызове, чтобы убедиться, что вы еще не подключены

return if request.path =~ /onboard/

Другим решением было бы иметь все действия вашего контроллера, относящиеся к включению, чтобы пропустить обратный вызов

skip_before_action :current_user_has_complete_profile_and_stripe_account, only: [:onboard]
1 голос
/ 31 марта 2019

Подход полностью действителен. Вам просто нужно проверить текущий контроллер и действия: если они уже на users_onboard_path, вам не нужно перенаправлять снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...