Ошибка при разработке перенаправлений: «Цепочка фильтров остановлена как: отрисованный или перенаправленный check_user»

#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, и теперь, похоже, она работает нормально 🙂