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

Mar*_*ark 24 authentication routes ruby-on-rails devise cancan

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

在登录后的什么时候我应该将用户重定向到他们自己的特定控制器/布局/视图?有没有一种方法来检查current_user.roleroutes.rb基础上,他们是否是一个项目经理或客户端,并设置了根(或重定向)?这是我在Devise某处可以做出的改变吗?

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

von*_*rad 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'
Run Code Online (Sandbox Code Playgroud)

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

  • http://stackoverflow.com/questions/4753871/how-can-i-redirect-a-users-home-root-path-based-on-their-role-using-devise/4754097#4754097是一个更好的实现,因为它不会仅为重定向创建新的控制器.此外,每次将用户重定向到root_path时,这将导致从浏览器到服务器的1次额外往返 (2认同)

col*_*rco 19

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

root :to => 'project_managers#index', :constraints => lambda { |request| request.env['warden'].user.role == 'project_manager' }
root :to => 'clients#index'
Run Code Online (Sandbox Code Playgroud)


Har*_*eak 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"
Run Code Online (Sandbox Code Playgroud)

请注意,在Rails 4中,您必须为每个根路由指定唯一的名称,有关详细信息,请参阅此问题.

  • 这个解决方案非常干净,语法更新 (2认同)

Pre*_*ids 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'
Run Code Online (Sandbox Code Playgroud)

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