Ruby on rails RubyonRails上的多种用户类型

Ruby on rails RubyonRails上的多种用户类型,ruby-on-rails,Ruby On Rails,我是RubyonRails新手,一直在学习教程。 但我需要更多的信息 我正在构建一个应用程序,允许访问各种类型的用户,他们是,学生,家长,教师和管理人员(所有人都有相同的属性) 到目前为止,我有一个用户模型,它有字段、电子邮件和密码,作为登录站点的凭据 然后我为每种类型的用户创建了一个模板。 模范学生 模范教师 .... 我想知道的是如何注册一个用户,指的是每种类型的用户,而我已经有了一个表用户 我一直在寻找,我意识到使用“设计”将是一个可行的解决方案,但我不太明白它是如何工作的 有人向我解释

我是RubyonRails新手,一直在学习教程。 但我需要更多的信息

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

然后我为每种类型的用户创建了一个模板。 模范学生 模范教师 ....

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

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


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

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

class User
  belongs_to: user_type
end

class UserType
  has_many: users
end
基于这种简单的一对多关系,您可以将表单中的用户类型传递给控制器,并让控制器负责创建/关联对象

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

这是一些非常简单、快速的代码,目的是让我的观点更加清晰。

好吧,下面是我将如何实现它

1) 创建帐户模型并在其迁移中添加多态引用,如下所示

  class Account < ActiveRecord:Migration
    def change
      create_table :accounts do |t|
        t.references :user, :polymorphic => true
        t.column :name, :string
      end
    end
  end
类帐户true
t、 列:名称,:字符串
结束
结束
结束
2) 在每个模型类中,例如学生类,我将添加以下代码行

  class Student < ActiveRecord::Base
    has_one :account, :as => :user
  end
class-Student:用户
结束
3) 帐户模型类中的

  class Account < ActiveRecord::Base
    belongs_to :user, :polymorphic => true
  end
类帐户true
结束
4) 为帐户模型使用设计生成器

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

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


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

如果您需要不同的应用程序权限,也许您希望为您的用户分配角色。这可以通过许多不同的方式实现。一个简单的方法是使用RolifGem:

正如其他答案所示,有几种方法可以解决这个问题。首先,确保您了解身份验证(创建用户并登录)和基于角色的授权(根据用户的角色控制对web应用程序不同部分的访问)之间的区别。您可以自己实现身份验证,但大多数Rails开发人员使用Desive gem,因为它健壮、功能齐全且经过良好测试。授权可以通过简单地添加到用户模型中来实现,尽管开发人员通常在复杂的应用程序中使用或gems

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

Rails 4.1中引入的活动记录的一个新特性Enum是实现基于角色的授权的最简单方法

创建迁移:

$ rails generate migration AddRoleToUsers role:integer
迁移将如下所示:

class AddRoleToUsers < ActiveRecord::Migration
  def change
    add_column :users, :role, :integer
  end
end
您可以在控制器中使用条件:

class UsersController < ApplicationController
  def index
    unless current_user.admin?
      redirect_to :back, :alert => "Access denied."
    end
    @users = User.all
  end
end
class UsersController“访问被拒绝。”
结束
@users=User.all
结束
结束
或者在视图中使用它:

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

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


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

    type
    属性是为单表继承保留的,在这种情况下什么是合适的,但至少您应该指定这个答案意味着STI,学生和教师模型应该继承自用户。谢谢您的评论@CV Gate。我修改了我的答案。这里我没有使用STI。谢谢你的回答。也许我不是很清楚,但我已经有了一个页面,可以通过我的用户模型创建一个用户(我可以登录和注销,并验证这个“表”的所有数据)。现在,我想把两个模型的数据(User和UserType-Student/Parents/Admin/etc)放在同一个页面中,然后将所有数据保存到各自的模型中。回答得很好!注意:我得到一个错误,说我不能在枚举中有一个字段“:parent”,因为这个类已经有一个方法“parent”,它是由活动记录定义的。谢谢Daniel,我喜欢使用自定义代码而不是gem。我只是想知道如果我想让用户拥有多个角色该怎么办。例如,用户有角色::teacher和:adminNice。另外,由于默认角色是在初始化之后设置的。迁移可以包括默认值,而不是使用回调。类似于:
    add_column:users,:role,:integer,默认值:0
    在学生模型/其他模型中是否仍有必要/可能将用户模型的用户标识定义为外键?谢谢
    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 %>