我正在开发一个项目管理应用程序,在应用程序中,我有 project_managers 和客户端。我正在使用Devise和CanCan进行身份验证/授权。
登录后的什么时候我应该将用户重定向到他们自己的特定控制器/布局/视图?有没有办法在current_user.role
中检查routes.rb
并根据他们是项目经理还是客户来设置根(或重定向)?这是我在Devise某处可以做出的改变吗?
提前感谢您的帮助! --mark
答案 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)