Когда пользователь входит в 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
Возвращает и удаляет (если это навигационный формат) 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'
Это сводило меня с ума, пока я не наткнулся на ваш комментарий. В моем случае проблема заключалась в том, что у меня был вызов журнала отладки
stored_location_for(resource)
, который уничтожил переменную сеанса до того, как он был фактически вызван. Как только я удалил это, он работал отлично.