我需要设置用户权限来编辑其他用户的个人资料。
我想要的是能够为每个用户设置可以处理的用户。所以,假设我们有 5 个用户:A、B、C、D、E
我希望 A 能够处理 B、C 和 D。我希望 B 能够处理 A、E、C。等等......
这是一对多还是多对多的关系?
我无法理解它,因为在我看来这是一对多的,因为一个用户有多个用户。但是由于用户本身可以由另一个用户处理,所以我认为它可能是多对多的。
我应该问自己什么问题来确定正确的关系?
我需要设置用户权限来编辑其他用户的个人资料。
我想要的是能够为每个用户设置可以处理的用户。所以,假设我们有 5 个用户:A、B、C、D、E
我希望 A 能够处理 B、C 和 D。我希望 B 能够处理 A、E、C。等等......
这是一对多还是多对多的关系?
我无法理解它,因为在我看来这是一对多的,因为一个用户有多个用户。但是由于用户本身可以由另一个用户处理,所以我认为它可能是多对多的。
我应该问自己什么问题来确定正确的关系?
这是一个多对多的关系,一个帐户可以编辑多个帐户,而多个帐户可以编辑一个帐户。
例子:
A can edit ABC
B can edit AC
C can edit BC
所以A可以被多个账户编辑(或者属于多个账户),并且可以编辑多个账户(或者有多个账户)
让我们解决您的问题,看看如何识别这种关系。
当您编写将检查用户是否被授权的代码时,您将拥有两个主要数据:执行编辑的用户和正在编辑的用户。因此,您的应用程序将要问的问题是“用户 A 可以编辑用户 B 吗?”
暂时忽略关系的语义,想想你将如何查找该问题的答案:
table can_edit:
requestor_id | edited_id | permission
=====================================
User A | User B | YES
User A | User C | YES
User A | User D | YES
User A | User E | NO
User B | User A | YES
User B | User C | YES
User B | User D | NO
etc...
使用此查找表,您可以确定谁有权编辑谁。但是,再看一下这张表所描述的内容。由于您正在查找是/否问题的答案,因此您可以更简单地表达它:
table can_edit:
requestor_id | edited_id | permission
=====================================
User A | User B | YES
User A | User C | YES
User A | User D | YES
User B | User A | YES
User B | User C | YES
etc...
在这里,我们删除了NO
权限。现在我们可以问: “我们是否有与我们的权限检查相匹配的条目?” can_edit
如果我们执行查找并且该行存在,那么我们可以允许访问。
现在,由于该permission
列将始终为YES
,因此包含它没有多大意义。所以现在我们有了一个基本上是用户 ID 关系列表的表。
在这一点上,我们可以使用数据库图绘制出关系的样子:
users:
user_id <-----+
email | can_edit:
pass_digest +-------- requestor_id
+========== edited_id
users: |
user_id <====+
email
pass_digest
如果我们查看rails 关联指南中的示例图,我们可以看到我们的图与has_many :through
和非常匹配has_and_belongs_to_many
。这些都描述了多对多关系。
就实现细节而言,您会注意到“用户 A 可以编辑用户 B 吗?” 和“用户 B 是用户 A 的朋友吗?” 本质上是同一个问题,只是对关系使用了不同的术语。有了这些知识,您会发现关于如何定义这种自引用has_many :through
关系的大量著作,例如Ryan Bates 的精彩截屏视频。
如果您不确定,我建议您阅读有关 Rails 关联的指南。有一些很好的例子和模式图片,可以说明问题:
http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association
这是一个多对多关系,因为在您的示例A
中是关系的双方。
我猜是 M2M 关系,因为在表中有多少?不止一个与霍伊有关,不止一个。