Rails 6, разрешить пользователю переходить на ожидаемую страницу после аутентификации

Когда пользователь входит в Devise, он попадает в new_car_path в соответствии с методом after_sign_in_path_for(). Однако бывают ситуации, когда Пользователь попытается перейти на определенную страницу, требующую аутентификации.

В моем примере вышедший из системы пользователь переходит непосредственно на «domain.com/compliance-form», эта страница требует, чтобы пользователь прошел аутентификацию, прежде чем добраться до нее, поэтому, как и ожидалось, он перенаправляется на форму входа. Когда пользователь входит в систему, он направляет его на путь «after_sign_in_path_for», который в данном случае является «new_car_path».

Однако, поскольку пользователь точно знает страницу, на которую он хочет перейти, я хочу, чтобы он перешел на «compliance_form_path» «domain.com/compliance-form».

Как мне это сделать?

  def after_sign_in_path_for(_resource=nil)
    new_car_path
  end

Если я добавлю stored_location_for(resource), как рекомендовал пользователь 11350468:

def after_sign_in_path_for(resource = nil)
  stored_location_for(resource) || new_car_path
end

Я получаю следующую ошибку,

NoMethodError в SessionsController#создать неопределенный метод `user_url' для #SessionsController:0x00007fc9f9bd1148 Вы имели в виду? 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

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

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"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Continue"}
  User Load (1.8ms)  SELECT "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "[email protected]"], ["LIMIT", 1]]
  ↳ app/controllers/sessions_controller.rb:6:in `create'
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["email", "[email protected]"], ["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" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5  [["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 возвращает true, но значение store_location_for(resource) возвращает nil.

Отсюда и ошибка. Решение Stored_location_for() ниже отлично работает!

Это сводило меня с ума, пока я не наткнулся на ваш комментарий. В моем случае проблема заключалась в том, что у меня был вызов журнала отладки stored_location_for(resource), который уничтожил переменную сеанса до того, как он был фактически вызван. Как только я удалил это, он работал отлично.

Eric Norcross 19.01.2021 01:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
291
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте следующее с помощником Stored_location_for

Возвращает и удаляет (если это навигационный формат) URL-адрес, сохраненный в сессия для заданный объем. Полезно для переадресации после регистрации:

Согласно вики, пожалуйста, добавьте ниже before_action в ваш application_controller:

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

Я благодарен за помощь, я получаю сообщение об ошибке NoMethodError в SessionsController#create undefined method `user_url'

Lefty 17.12.2020 17:10

Другие вопросы по теме