我们中的许多人可能遇到过这种情况。我想构建一个支持多个用户角色的应用,并且不想在该过程中使用宝石。
我有4种类型的用户:
Admin
Teacher
Student
Librarian
Admin
很简单,他只需要两列,username
和password
。开头的用户表仅包含以下值:
username, password, admin, teacher, student, librarian
列admin, teacher, student, librarian
是布尔值,用于定义用户是否具有特定角色。管理员将admin
至true
,其他所有列均为false。
当我们引入仅特定于一个角色的其他列时,问题就出现了。我们为用户表提供了以下列:
id
username
password
admin
teacher
student
librarian
teacher_column1
teacher_column2
teacher_column3
student_column1
student_column2
student_column3
etc...
创建用户时,我们需要使用空值填充许多列。如果我们创建一个教师,只有图书管理员和学生需要的所有列都填充空值。
在人们问起这个问题的几个地方,他们被建议做STI,所以他们会以这样的结局结束:
class User < ActiveRecord::Base
end
class Admin < User
end
class Teacher < User
end
class Student < User
end
这看起来好多了,但仍会引入很多空值。
其他想法是为不同的用户类型细节引入4个新表。像这样:
用户表:
id
username
password
admin
teacher
student
librarian
教师表:
user_id
teacher_column1
teacher_column2
teacher_column3
学生表:
user_id
username
password
student_column1
student_column2
student_column3
对于图书管理员和管理员来说也是如此。在检查角色后的用户创建过程中,将创建该用户的特定表中的新行。
您如何看待这最后一种方法?缺点和优点?
这是创建具有多个用户角色的系统的正确方法吗?谢谢。
答案 0 :(得分:4)
不要为每个权限使用不同的列。
为具有以下列的用户创建一个表:
username
password
user_type
user_type
将是%w{admin teacher student librarian}
中的值,然后使用您在帖子中提到的单表继承。
为Role创建一个表:
name
然后创建一个表格以将角色与用户联系起来:
role_id
user_id
为Permission创建一个表:
name
然后创建一个表以将权限绑定到角色:
permission_id
role_id
最后你会得到:
包含表格的3个模型:User
,Role
和Permission
4个没有表格的模型,从User
开始:Admin
,Teacher
,Student
和Librarian
2个没有型号的表:users_roles
和roles_permissions
此外,如果有许多列对每个用户类型都是唯一的,那么我建议为每个用户使用不同的模型+表格,并使user
成为Role
多态。
通过这种方式,您可以轻松创建新角色/权限,修改特定角色的权限,以及轻松添加/删除特定用户的角色。