Rails, Active Admin, Devise, маршруты

Я работал с Rails, Active Addmin и cancancan. Все работает нормально, кроме одного. Недавно я добавил отдельные пространства имен для пользователей типа admin и клиентов.

До этого изменения я перенаправлял всех аутентифицированных пользователей на одну и ту же активную панель администратора таким образом (routes.rb):

  devise_scope :user do
    authenticated :user do  
        root :to => 'admin/dashboard#index', as: :authenticated_root
    end
    unauthenticated :user do
      root :to => 'pages#index', as: :unauthenticated_root
    end
  end

В настоящее время мне нужно как-то добавить дополнительное условие, которое будет проверять, есть ли у аутентифицированного пользователя роль admin или client.

Моя идея состояла в том, чтобы сделать что-то вроде этого:

devise_scope :user do
    authenticated :user do 
      if current_user.role?(:Architect) || current_user.role?(:Admin) 
        root :to => 'admin/dashboard#index', as: :authenticated_root
      else 
        root :to => 'clients/dashboard#index', as: :authenticated_client
      end
    end
    unauthenticated :user do
      root :to => 'pages#index', as: :unauthenticated_root
    end
  end

Но я получаю сообщение об ошибке: неопределенная локальная переменная или метод `current_user' Кто-нибудь знает, как я могу проверить роль пользователя в маршрутах? Есть ли лучший способ сделать это?


person Michal    schedule 24.03.2016    source источник
comment
Вы можете проверить роль пользователя в applicationcontroller перед фильтром действий. Раньше я не обращался к current_user в route.rb.   -  person Muhammad Yawar Ali    schedule 24.03.2016


Ответы (2)


Корень — это файл конфигурации, отвечающий за определение маршрутов, вы не можете получить доступ к каким-либо переменным сеанса в файлах конфигурации.

Если вы хотите перенаправить пользователя после входа в систему, вы можете использовать метод after_sign_in_path_for в Devise::SessionsController

class SessionsController < Devise::SessionsController

    def after_sign_in_path_for(resource)
        if resource.role?(:Architect) || resource.role?(:Admin) 
            authenticated_root_url
        else
            authenticated_client_url
        end 
    end
end

В вашем маршруте вам нужно указать пользовательский session_controller

devise_for :user, :controllers => {:sessions => "sessions"}
person Abdoo Dev    schedule 24.03.2016
comment
Этот работал для меня. Предложения Мухаммеда тоже ценны, но это решение почти не требовало изменений в коде. 1. Из route.rb удалил весь блок, начиная с devise_scope... 2. Добавил: devise_for :users, controllers: {sessions: 'users/sessions', registrations: 'users/registrations', passwords: 'users/passwords'}, path_names: { sign_in: 'login', sign_out: 'logout' } - person Michal; 24.03.2016
comment
3. в /users/sessions_controller.rb добавил: def after_sign_in_path_for(resource) if resource.role?(:Architect) || resource.role?(:Admin) admin_dashboard_path else clients_dashboard_path end end - person Michal; 24.03.2016
comment
@Michal вам также нужно будет добавить перед фильтром, если пользователь вручную вводит URL-адрес. - person Muhammad Yawar Ali; 24.03.2016

Контроллер страниц:

class PageController < ApplicationController

  before_filter :check_route, :only => [:index]

  def check_route
    return unless user_signed_in?
    if current_user.role?(:Architect) || current_user.role?(:Admin)
      redirect_to :controller => 'admin/dashboard', :action => 'index'
    else
      redirect_to :controller => 'clients/dashboard', :action => 'index'
    end
  end
end

маршруты.rb:

root :to => 'pages#index', as: :unauthenticated_root
person Muhammad Yawar Ali    schedule 24.03.2016