Ruby on rails 什么';使用Rails/Desive处理多个作用域/角色的登录和注销的最佳方法是什么?
我一直在这个网站上搜索Desive RDocs,Google,寻找我问题的答案,但运气不好 假设我有四个Desive作用域/角色,每个都有自己的属性、登录页面和单独的web流:Ruby on rails 什么';使用Rails/Desive处理多个作用域/角色的登录和注销的最佳方法是什么?,ruby-on-rails,ruby,ruby-on-rails-3,devise,scopes,Ruby On Rails,Ruby,Ruby On Rails 3,Devise,Scopes,我一直在这个网站上搜索Desive RDocs,Google,寻找我问题的答案,但运气不好 假设我有四个Desive作用域/角色,每个都有自己的属性、登录页面和单独的web流: 学生 教授 院长 学院 所有这些都使用用户类,并具有以下共同属性 身份证 名字 电子邮件 密码 角色 以下是我为设置此功能而建立的路线示例: devise_for :students, :class_name => 'User' devise_for :professors, :class_name =&g
- 学生
- 教授
- 院长
- 学院
- 身份证
- 名字
- 电子邮件
- 密码
- 角色
devise_for :students, :class_name => 'User'
devise_for :professors, :class_name => 'User'
devise_for :deans, :class_name => 'User'
devise_for :faculties, :class_name => 'User'
devise_for :users
然后我生成了Desive范围的视图,并对这些视图进行了处理
之后,我必须在我的应用程序控制器中添加一些代码,以覆盖Desive::RegistrationController,该控制器希望将所有内容路由到根路径:
def after_sign_in_path_for(resource)
user_role = resource.role
case user_role
when "professor"
professors_url
when "faculty"
faculties_url
when "dean"
deans_url
when "student"
students_url
else
root_path
end
end
def after_sign_out_path_for(resource)
case resource
when :faculty
new_faculty_session_path
when :professor
new_professor_session_path
when :dean
new_dean_session_path
when :student
new_student_session_path
else
root_path
end
end
我可以访问优秀的帮助程序,如登录?,它告诉我上述任何一个作用域中的任何用户是否已登录。伟大的现在我需要为当前用户提供类似的功能
我可以访问以下帮助程序
- 当前学生
- 现任教授
- 当前院长
- 现任教职员工
<% if student_signed_in? %>
<div style="float: right;">Welcome <%= current_student.name %></div>
<div>
<%= link_to('Logout', destroy_student_session_path, :method => :delete) %>
</div>
<% end %>
如果这种方法可行,我会这样做,但是如果我决定在将来添加更多的角色或通用功能,这似乎是非常低效和乏味的
一定有更好的办法吗?这让我觉得我在错误地使用Desive,或者只是遗漏了一些东西。你从Ryan bates那里退房了吗?它允许您仅使用Desive用户模型,并根据用户模型中的角色定义能力。然后,它允许您访问助手方法can?
和cannot?
,以进一步定义您的能力
编辑:我会将属性移动到引用的模型,并使用CanCan引导web流。您在web上看到的示例并不总是显示CanCan将为您提供的全部功能。您可以在登录页上放置链接,将其指向相应的登录页,每个登录页都具有相同的Desive登录表单。在的路径中为签名后保留的逻辑,并使用CanCan锁定受限操作。这简化了路由和整个应用程序逻辑和设计。此外,仅使用一种型号,故障排除和设计错误就容易了75%。根据对上述答案的评论,另一种选择是使用多个rails应用程序(每个角色一个),或者在它们之间共享同一个DB(见此),或者制作另一个仅用于身份验证和授权的应用程序,并通过它管理所有登录 不过,如果你不想使用一个应用程序,上述解决方案实际上只是一种退路。我建议您继续做您现在正在做的事情,确定范围并制定能够处理每种情况的方法 使用精心设计的方法,您可以做得更好一些。例如,修改
destroy\u resource\u session\u path
以接受参数current\u user
,该参数分配给current\u professor。。。当前会话路径不为零,然后调用销毁会话路径
。要进一步详细说明如何做到这一点:
您不需要在应用程序中定义明确的角色,只需要将每个角色路由到一组不同的模型/视图/控制器,因此最好的方法是创建一个单独的控制器来确定角色,并根据用户角色将请求路由到相应的控制器
编辑:
总的来说,我认为您的做法是正确的,但是如果您将处理不同用户的方法(如您拥有的2个)复制到一个单独的控制器中,并执行诸如销毁资源\u会话\u路径
和当前资源
之类的操作,您可以做得更好。类似地,将
的的在的路径中的和的在路径中的方法添加到该新控制器中
关键是新控制器应该处理不同类型用户之间的差异,因此添加新类型的用户非常简单,只需向该控制器添加几行代码,然后修改routes.rb
只需在该控制器中存储一个角色列表。然后,您可以修改方法以使用集合来确定存在哪些角色,因此您所要做的就是在集合中添加一个条目,并在routes.rb
中添加一个条目以添加新角色。例如,您可以在为(资源)在路径中签名后将修改为:
def after_sign_in_path_for(resource)
user_role = resource.role
if (set_of_roles.include?(user_role))
return #{user_role}_url
else
return root_path
end
end
注意,{..}
是在ruby中插入字符串的方式,因此ruby中的{user\u role}\u url
相当于Java中的user\u role+“\u url”
使用这样的方法,添加新角色所要做的唯一事情就是为该角色创建一个新视图,在routes.rb
中定义一个名为role\u name
的路由,然后将该角色添加到set\u of\u roles
我建议在使用单点登录之前先研究一下这个想法——我对它不太熟悉,但我所链接到的问题的答案表明它过于复杂了 经过更多的研究,我发现了一种名为CanTango的宝石,它正是我想要的。它与Desive一起工作,并处理多个用户模型类型。看一看
谢谢你们回答我的问题,伙计们。我
def current_resource
current_professor unless current_professor.nil?
current_student unless current_student.nil?
current_dean unless current_dean.nil?
current_faculty unless current_faculty.nil?
end
def destroy_resource_session_path
destroy_professor_session_path unless current_professor.nil?
destroy_student_session_path unless current_student.nil?
destroy_dean_session_path unless current_dean.nil?
destroy_faculty unless current_faculty.nil?
end
def after_sign_in_path_for(resource)
user_role = resource.role
if (set_of_roles.include?(user_role))
return #{user_role}_url
else
return root_path
end
end