Как я могу перенаправить домашний (корневой) путь пользователя в зависимости от его роли с помощью Devise? - PullRequest
24 голосов
/ 21 января 2011

Я работаю над приложением для управления проектами, и в приложении у меня есть project_managers и клиентов . Я использую Devise и CanCan для аутентификации / авторизации.

В какой момент после входа в систему я должен перенаправить пользователя на его собственный конкретный контроллер / макет / представления? Есть ли способ проверить current_user.role в routes.rb и установить root (или перенаправить) в зависимости от того, являются они менеджером проекта или клиентом? Это изменение, которое я могу сделать где-нибудь в Devise?

Заранее спасибо за любую помощь! --Mark

Ответы [ 5 ]

37 голосов
/ 21 января 2011

Ваш routes.rb файл не будет иметь никакого представления о роли пользователя, поэтому вы не сможете использовать его для назначения определенных корневых маршрутов.

Что вы можете сделать, это настроитьконтроллер (например, passthrough_controller.rb), который в свою очередь может читать роль и перенаправлять.Примерно так:

# passthrough_controller.rb
class PassthroughController < ApplicationController
  def index
    path = case current_user.role
      when 'project_manager'
        some_path
      when 'client'
        some_other_path
      else
        # If you want to raise an exception or have a default root for users without roles
    end

    redirect_to path     
  end
end

# routes.rb
root :to => 'passthrough#index'

Таким образом, у всех пользователей будет одна точка входа, которая, в свою очередь, перенаправит их на соответствующий контроллер / действие в зависимости от их роли.

19 голосов
/ 03 августа 2012

Самое простое решение - использовать lambda:

root :to => 'project_managers#index', :constraints => lambda { |request| request.env['warden'].user.role == 'project_manager' }
root :to => 'clients#index'
15 голосов
/ 02 февраля 2014

Другой вариант - передать процедуру методу authenticated следующим образом (в этом примере я использую rolify):

authenticated :user, ->(u) { u.has_role?(:manager) } do
  root to: "managers#index", as: :manager_root
end

authenticated :user, ->(u) { u.has_role?(:employee) } do
  root to: "employees#index", as: :employee_root
end

root to: "landing_page#index"

Обратите внимание, что в Rails 4 у ​​вас есть для указания уникального имени для каждого корневого маршрута, подробнее см. эту проблему .

7 голосов
/ 21 января 2011

Я делаю это в приложении Rails 3, которое использует Warden.Поскольку Devise построен поверх Warden, я думаю, что он будет работать для вас, но обязательно поэкспериментируйте с ним, прежде чем полагаться на него.Будет использоваться ProjectManagersController - если это не так, будет использоваться ClientsController.Если они вообще не вошли в систему, env['warden'].user будет равно нулю, и вы получите ошибку, так что вы, вероятно, захотите обойти это, но это поможет вам начать.

3 голосов
/ 24 октября 2011
...