如何使用Devise根据角色重定向用户的主(根)路径?

我正在开发一个项目管理应用程序,在应用程序中,我有project_managers客户端 。 我正在使用Devise和CanCan进行身份validation/授权。

在登录后的什么时候我应该将用户重定向到他们自己的特定控制器/布局/视图? 有没有办法检查routes.rb current_user.role并根据它们是项目经理还是客户端设置root(或重定向)? 这是我在Devise某处可以做出的改变吗?

在此先感谢您的帮助! – 标记

您的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' 

这样,所有用户都将拥有一个入口点,进而根据其角色将它们重定向到适当的控制器/操作。

最简单的解决方案是使用lambda

 root :to => 'project_managers#index', :constraints => lambda { |request| request.env['warden'].user.role == 'project_manager' } root :to => 'clients#index' 

另一个选择是将proc传递给这样的经过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中,您必须为每个根路由指定唯一的名称,有关详细信息,请参阅此问题 。

我在使用Warden的Rails 3应用程序中执行此操作。 由于Devise是建立在Warden之上的,我认为它对你有用,但在依赖之前一定要先试验一下。

 class ProjectManagerChecker def self.matches?(request) request.env['warden'].user.role == 'project_manager' end end # routes.rb get '/' => 'project_managers#index', :constraints => ProjectManagerChecker get '/' => 'clients#index' 

如果用户的角色是“project_manager”,则将使用ProjectManagersController – 如果不是,则将使用ClientsController。 如果他们根本没有登录, env['warden'].user将是nil并且你会收到错误,所以你可能想要解决这个问题,但这会让你开始。

博客文章的实施http://minhajuddin.com/2011/10/24/how-to-change-the-rails-root-url-based-on-the-user-or-role/