我是Ruby on Rails的新手,并且一直在关注本教程。 但我需要更多信息。
我正在构建一个允许访问各种类型用户的应用程序,他们是学生,家长,教师和管理员(都具有相同的属性) 到目前为止,我有一个用户模型,其中包含电子邮件和密码字段,用作登录网站的凭据..
然后我为每种类型的用户提供了一个模板。 模特学生 模范老师 ....
我想知道的是如何注册用户,引用每种类型的用户,并且我已经有一个用户表。
我一直在搜索,我意识到使用'设计'将是一个可行的解决方案,但不太明白这是如何工作的。
有人向我解释了最好的方法吗?
答案 0 :(得分:35)
正如其他答案所示,有几种方法可以解决这个问题。首先,确保您了解身份验证,(创建用户和登录)和基于角色的授权之间的区别(根据Web应用程序的不同部分控制访问权限)关于用户的角色)。您可以自己实现身份验证,但大多数Rails开发人员使用Devise gem,因为它功能强大,功能齐全且经过充分测试。虽然开发人员经常将CanCanCan或Pundit宝石用于复杂的应用程序,但可以通过对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 %>
通常,如果访问控制向控制器添加了大量代码,建议您使用CanCanCan或Pundit,因为您可以将复杂的授权逻辑移动到中心位置与控制器隔离(&#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])
这是一些非常简单且快速汇总的代码,旨在使我的观点更加清晰。