Ruby on Rails上的多种用户类型

tel*_*lma 17 ruby-on-rails

我是Ruby on Rails的新手,并且一直在关注本教程.但我需要更多信息.

我正在构建一个应用程序,允许访问各种类型的用户,他们是,学生,家长,教师和管理员(都具有相同的属性)到目前为止,我有一个用户模型,其中包含字段,电子邮件和密码,作为登录网站的凭据..

然后我为每种类型的用户都有一个模板.模特学生模范老师....

我想知道的是如何注册用户,引用每种类型的用户,我已经有一个用户表.

我一直在寻找,我意识到使用'设计'将是一个可行的解决方案,但不太明白这是如何工作的.

有人向我解释最好的方法吗?

Dan*_*hoe 36

其他答案表明,有几种方法可以解决这个问题.首先,确保您了解身份验证(创建用户和登录)和基于角色的授权(根据用户角色控制对Web应用程序不同部分的访问)之间的区别.您可以自己实现身份验证,但大多数Rails开发人员使用Devise gem,因为它功能强大,功能齐全且经过充分测试.虽然开发人员经常将CanCanCanPundit gems用于复杂的应用程序,但可以通过对User模型的简单添加来实现授权.

对于您描述的用例,我建议在您的用户模型中实现一种非常基本的基于角色的授权形式.首先,您必须使用Devise创建用户模型.

Rails 4.1中引入的Active Record,Enum的一个新功能是实现基于角色的授权的最简单方法.

创建迁移:

$ rails generate migration AddRoleToUsers role:integer
Run Code Online (Sandbox Code Playgroud)

迁移将如下所示:

class AddRoleToUsers < ActiveRecord::Migration
  def change
    add_column :users, :role, :integer
  end
end
Run Code Online (Sandbox Code Playgroud)

将代码添加到User模型以实现Enum:

class User < ActiveRecord::Base
  enum role: [:student, :parent, :teacher, :admin]
  after_initialize :set_default_role, :if => :new_record?

  def set_default_role
    self.role ||= :student
  end

end
Run Code Online (Sandbox Code Playgroud)

您可以定义角色的名称,如有必要,可以根据需要更改名称(每个用户记录存储的整数值保持不变).Active Record会将属性的分配限制为预定义值的集合,因此您不必添加任何代码来将角色的名称限制为已定义的集合.最重要的是,枚举带有一组便捷方法,允许您直接查询角色而无需任何额外的代码.对于上面显示的enum属性,您可以使用以下方法:

User.roles # => {"student"=>0, "parent"=>1, "teacher"=>2, "admin"=>1} # list all roles
user.student! # make a student user
user.student? # => true # query if the user is a student
user.role # => "student" # find out the user’s role
@users = User.student # obtain an array of all users who are students
user.role = 'foo' # ArgumentError: 'foo' is not a valid, we can’t set invalid roles
Run Code Online (Sandbox Code Playgroud)

您可以在控制器中使用条件:

class UsersController < ApplicationController
  def index
    unless current_user.admin?
      redirect_to :back, :alert => "Access denied."
    end
    @users = User.all
  end
end
Run Code Online (Sandbox Code Playgroud)

或者在视图中使用它:

<% if current_user.parent? %>
  <li><%= link_to 'Grade Reports', some_path %></li>
<% end %>
Run Code Online (Sandbox Code Playgroud)

通常,如果访问控制向控制器添加了大量代码,则建议您使用 CanCanCanPundit,因为您可以将复杂的授权逻辑移动到与控制器隔离的中央位置("瘦控制器").但是,如果您的需求与您描述的一样简单,则控制器中基于角色的授权是最佳的.

我编写了一个Rails Pundit教程,该教程比较了这两种方法,并提供了有关基于角色的简单授权以及Pundit基于角色的授权的更多详细信息.


lsa*_*fie 0

在最简单的形式中,您希望能够在注册时选择用户类型。

class User
  belongs_to: user_type
end

class UserType
  has_many: users
end
Run Code Online (Sandbox Code Playgroud)

基于这种简单的一对多关系,您可以将表单中的 user_type 传递给控制器​​,并让控制器负责创建/关联对象

user = User.create(params[:user])
user.user_type = UserType.find(params[:user][:user_type])
Run Code Online (Sandbox Code Playgroud)

这是一些非常简单且快速组合在一起的代码,旨在使我的观点更加清晰。