Ruby on Rails上的多种用户类型

时间:2014-06-29 20:11:06

标签: ruby-on-rails

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

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

然后我为每种类型的用户提供了一个模板。 模特学生 模范老师 ....

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

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

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

4 个答案:

答案 0 :(得分:35)

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

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

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

创建迁移:

$ rails generate migration AddRoleToUsers role:integer

迁移将如下所示:

class AddRoleToUsers < ActiveRecord::Migration
  def change
    add_column :users, :role, :integer
  end
end

将代码添加到您的用户模型以实现枚举:

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

您可以定义角色的名称,如有必要,可以根据需要更改名称(每个用户记录存储的整数值保持不变)。 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

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

class UsersController < ApplicationController
  def index
    unless current_user.admin?
      redirect_to :back, :alert => "Access denied."
    end
    @users = User.all
  end
end

或者在视图中使用它:

<% if current_user.parent? %>
  <li><%= link_to 'Grade Reports', some_path %></li>
<% end %>

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

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

答案 1 :(得分:2)

好吧,我将如何实现它。

1)创建帐户模型并在其迁移中添加多态参考,如此

  class Account < ActiveRecord:Migration
    def change
      create_table :accounts do |t|
        t.references :user, :polymorphic => true
        t.column :name, :string
      end
    end
  end

2)在每个模型类中,例如学生类我将添加以下代码行

  class Student < ActiveRecord::Base
    has_one :account, :as => :user
  end

3)在帐户模型类

  class Account < ActiveRecord::Base
    belongs_to :user, :polymorphic => true
  end

4)对帐户模型使用设计生成器。

5)最大的挑战是创建一个新的学生,基本上你将创建一个帐户记录,然后将此帐户记录分配给新创建的学生记录。

a)有两种方法可以做到:       *使用嵌套表格。       *使用简单的表格,让控制器完成工作。

我会鼓励第二种选择,选择最适合你的选项,如果你有任何问题请告诉我。

答案 2 :(得分:1)

如果您需要不同的应用权限,可能需要为用户分配角色。这可以通过许多不同的方式实现。一个简单的方法是使用Rolify gem:https://github.com/EppO/rolify

答案 3 :(得分:0)

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

class User
  belongs_to: user_type
end

class UserType
  has_many: users
end

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

user = User.create(params[:user])
user.user_type = UserType.find(params[:user][:user_type])

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