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

时间:2011-01-20 23:28:50

标签: ruby-on-rails authentication routes devise cancan

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

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

提前感谢您的帮助! --mark

5 个答案:

答案 0 :(得分:37)

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

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

答案 1 :(得分:19)

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

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

答案 2 :(得分:15)

另一个选择是将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中,您为每个根路由指定唯一名称,有关详细信息,请参阅this issue

答案 3 :(得分:7)

我在使用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将为零,你会收到错误,所以你可能想要解决这个问题,但这会让你开始。

答案 4 :(得分:3)