Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 什么';使用Rails/Desive处理多个作用域/角色的登录和注销的最佳方法是什么?_Ruby On Rails_Ruby_Ruby On Rails 3_Devise_Scopes - Fatal编程技术网

Ruby on rails 什么';使用Rails/Desive处理多个作用域/角色的登录和注销的最佳方法是什么?

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

我一直在这个网站上搜索Desive RDocs,Google,寻找我问题的答案,但运气不好

假设我有四个Desive作用域/角色,每个都有自己的属性、登录页面和单独的web流:

  • 学生
  • 教授
  • 院长
  • 学院
所有这些都使用用户类,并具有以下共同属性

  • 身份证
  • 名字
  • 电子邮件
  • 密码
  • 角色
以下是我为设置此功能而建立的路线示例:

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