#ruby-on-rails #devise
#ruby-on-rails #разработка
Вопрос:
Я работаю над небольшим приложением Rails (5), используя Devise для аутентификации. Я следовал руководству по созданию нескольких моделей (https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models ), и теперь я хочу настроить перенаправления, в частности after_sign_in_path
… Но затем я заметил следующую ошибку, которая появляется после входа в систему:
Started POST "/athlete/login" for 127.0.0.1 at 2019-03-25 17:03:32 0100
Processing by Athletes::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xsZXnYOPJKLpveg1xr5D10i8DF5HGCH50pstEg85p Y1OLIAmKMunYIV BV5PJtgd51upy6i22VBMlQr5gtpEQ==", "athlete"=>{"email"=>"athlete@test.me", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Connexion"}
Athlete Load (8.0ms) SELECT "athletes".* FROM "athletes" WHERE "athletes"."email" = $1 ORDER BY "athletes"."id" ASC LIMIT $2 [["email", "athlete@test.me"], ["LIMIT", 1]]
↳ app/controllers/concerns/accessible.rb:13
Redirected to http://localhost:3000/athlete/onboarding
Filter chain halted as :check_user rendered or redirected
Completed 302 Found in 387ms (ActiveRecord: 8.0ms)
В результате after_sign_in_path_for
метод никогда не вызывается, но я не знаю почему… Я предполагаю, что это может быть связано с настройкой контроллера, которую я сделал (я добавил действия), но если да, то как я мог это исправить? Я начинаю с Rails, поэтому любая помощь была бы очень желанной!
Заранее спасибо!
Вот мой код (надеюсь, это будет полезно):
registrations_controller.rb
class Athletes::RegistrationsController < Devise::RegistrationsController
include Accessible
skip_before_action :check_user, except: [:new, :create]
before_action :configure_account_update_params, only: [:update]
# GET /resource/onboarding
def onboarding
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
end
# GET /resource/profile
def profile
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
end
# GET /resource/physical_profile
def physical_profile
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
end
protected
def after_sign_up_path_for(resource)
onboarding_athlete_registration_path
end
def update_resource(resource, params)
resource.update_without_password(params)
end
def configure_account_update_params
added_attrs = [
:avatar,
:firstname,
:lastname,
:birthdate,
:gender,
:phone,
:city,
:subscribe_newsletter,
:goal,
:practice_frequency,
:height,
:weight,
training_zone_attributes: [:id, :name, :address, :zip_code, :city]
]
devise_parameter_sanitizer.permit(:account_update, keys: added_attrs)
end
end
sessions_controller.rb
class Athletes::SessionsController < Devise::SessionsController
include Accessible
skip_before_action :check_user, only: :destroy
protected
def after_sign_in_path_for(resource)
if resource.profile_completion < 100
onboarding_athlete_registration_path
else
athlete_dashboard_path
end
end
end
routes.rb
Rails.application.routes.draw do
get '/coach/settings', to: redirect('/coach/settings/profile')
get '/athlete/settings', to: redirect('/athlete/settings/profile')
devise_for :athletes, path: "athlete", path_names: {
sign_in: "login",
sign_out: "logout",
sign_up: "register",
edit: "settings"
}, controllers: {
sessions: "athletes/sessions",
registrations: "athletes/registrations",
confirmations: "athletes/confirmations",
passwords: "athletes/passwords",
unlocks: "athletes/unlocks",
invitations: "athletes/invitations"
}
devise_for :coaches, path: "coach", path_names: {
sign_in: "login",
sign_out: "logout",
sign_up: "register",
edit: "settings"
}, controllers: {
sessions: "coaches/sessions",
registrations: "coaches/registrations",
confirmations: "coaches/confirmations",
passwords: "coaches/passwords",
unlocks: "coaches/unlocks"
}
as :athlete do
get "athlete/onboarding", to: "athletes/registrations#onboarding", as: "onboarding_athlete_registration"
get "athlete/settings/profile", to: "athletes/registrations#profile", as: "profile_athlete_registration"
get "athlete/settings/physical_profile", to: "athletes/registrations#physical_profile", as: "physical_profile_athlete_registration"
get "athlete/onboarding", to: "athletes/registrations#onboarding", as: :authenticated_athlete_root
end
as :coach do
get "coach/onboarding", to: "coaches/registrations#onboarding", as: "onboarding_coach_registration"
get "coach/settings/profile", to: "coaches/registrations#profile", as: "profile_coach_registration"
get "coach/settings/trainings", to: "coaches/registrations#trainings", as: "trainings_coach_registration"
get "coach/settings/infos", to: "coaches/registrations#infos", as: "infos_coach_registration"
get "coach/settings/subscription", to: "coaches/registrations#subscription", as: "subscription_coach_registration"
get "coach/onboarding", to: "coaches/registrations#onboarding", as: :authenticated_coach_root
end
scope "coach", as: "coach" do
resource :calendar, only: [:show, :update]
get "calendar", to: "calendars#edit"
get "dashboard", to: "coaches#dashboard"
end
scope "athlete", as: "athlete" do
get "dashboard", to: "athletes#dashboard"
end
resources :coaches, only: [:show] do
resource :calendar, only: :show, defaults: { format: :json }
resources :events, only: [:index, :update], defaults: { format: :json }
end
scope "booking", as: "booking" do
resources :coaches, only: [:index, :show]
resources :events, except: :index do
get "/training", to: "events#training"
get "/confirm", to: "events#confirm"
end
end
root to: "welcome#index"
end
доступно.rb
module Accessible
extend ActiveSupport::Concern
included do
before_action :check_user
end
protected
def check_user
if current_coach
flash.clear
redirect_to(authenticated_coach_root_path) amp;amp; return
elsif current_athlete
flash.clear
redirect_to(authenticated_athlete_root_path) amp;amp; return
end
end
end
Комментарии:
1. вы не пропускаете
check_user
дляlogin
действия в вашемAthletes::SessionsController
. Добавьте это какskip_before_action :check_user, only: [:destroy, :login]
Ответ №1:
Вы были совершенно правы @ fanta, даже если проблема, возможно, требовала больше времени для решения… Мне пришлось изменить правило следующим образом: skip_before_action :check_user, only: [:destroy, :create]
, как вы сказали, но также изменить мои контроллеры. Вместо того, чтобы использовать мои пользовательские действия для пользователей внутри контроллеров Devise, я создал для них стандартные контроллеры Rails.
Я думаю, я напортачил с маршрутизацией Devise, и теперь, похоже, она работает нормально 🙂