不确定如何在 Mongoid 中使用标志来建模多对多关系
我有两个实体:项目和用户。这些是在 Rails 中使用 Mongoid 以及两个文档实例(用户和项目)进行建模的。
在该系统中,一个用户可以创建一个项目,但多个用户可以关注多个项目。例如,作为user_id 1,我创建了project_id 1。但是user_ids 10、11、40和60都遵循project_id 1。我需要表示用户和项目之间的多对多关系,并将特定的user_id表示为项目的创建者,为其分配编辑权限。
实际上,当用户登录时,他需要能够看到他正在关注的所有项目,包括他创建的任何项目,以及与其他用户创建的其他项目混合在一起的项目。他特殊的创作者身份根本不会影响这个名单。当用户查看特定项目时,他需要能够查看关注该项目的所有用户,如果他是创建者,他可以添加新的关注者并删除现有的关注者。
在 RDBMS 中,我将使用表 users
、projects
和带有 is_creator
标志的 users_projects
连接表来表示这一点。这可以让我轻松选择用户可以看到哪些项目,以及哪些用户是项目的关注者,包括哪些用户是项目的创建者。
Mongoid 支持多对多关系,但与 RDBMS 不同,我无法在关系上添加标记。相反,我想将一个 creator
字段添加到 projects
文档中,其中将包含一个返回到 _id
字段的链接用户文档。
用户->项目关系可能看起来像这样
class User
has_and_belongs_to_many :projects
end
class Project
has_and_belongs_to_many: users
end
,但我不知道如何映射创建者->created_projects关系。我相信我可以在 Project
中引用用户创建者,例如 belongs_to :creator, :class_name =>; 'User'
但我不知道如何设置另一方。
如何在 Mongoid 中最好地建模这些关系?
I have two entities, projects and users. These are modeled in Rails using Mongoid with two Document instances, User and Project.
In this system, one user can create one project, but many users can follow many projects. For example, as user_id 1 I've created project_id 1. But user_ids 10, 11, 40, and 60 all follow project_id 1. I need to represent a many-to-many relationship between users and projects, and represent a specific user_id as the creator of the project, to assign him editing rights.
Practically speaking, when a user logs-in, he needs to be able to see all projects that he is following, including any that he created, commingled with other projects created by other users. His special creator status wont influence this list at all. When a user looks at a specific project, he needs to be able to view all users following a project, and if he's a creator, he can add new followers and delete existing ones.
In a RDBMS I would represents this with tables users
, projects
and a users_projects
join table with a flag of is_creator
. This would easily let me select which projects a user can see, and which users are followers, including which users are creators, of projects.
Mongoid supports many-to-many relationships, but unlike in an RDBMS there's no way for me to put a flag on the relationship. Instead, I'm thinking I'll add a creator
field to the projects
document, which will contain a link back to an _id
field on the users document.
The user->projects relationship might look like this
class User
has_and_belongs_to_many :projects
end
class Project
has_and_belongs_to_many: users
end
But I can't figure out how to map the creator->created_projects relationship. I believe I can reference a user creator in Project
like belongs_to :creator, :class_name => 'User'
but I'm not sure how to set up the other side.
How best can I model these relationships in Mongoid?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第二个版本使用较少的空间,但您需要额外的查询来获取用户详细信息,例如用户名。对象 ID 最多 12 个字节。文档大小为 16mb,因此该数组可以容纳大约 130 万个用户 ID(理论上!)..
如下:
user.rb
project.rb
如何使用它:
the second version uses less space but you need an extra query to get the user details like usernames. An object ID has 12bytes, max. document size is 16mb so the array could hold around 1.3M user ids (theoretically!)..
here you go:
user.rb
project.rb
How to work with it:
创建一个嵌入文档,其中包含所有关注者及其 user_id 和用户名,这样您就不必查询关注者的用户名。
优点:
缺点:
如果用户更改了他的名字,您将必须更新他的所有“关注”,但是更新频率
与您查找关注的项目的频率相比,您是否会更改您的名字;)
如果您每个项目有数千名关注者,您可能会达到 16mb 的文档限制
user.rb
project.rb
follower.rb
如何使用它:
PS:如果您想要一个更简单的解决方案,你可以嵌入项目中的 ObjectID (user_ids) 数组,并使用原子更新
$addToSet
和$pullAll
来添加/删除关注者。但是您需要一个额外的查询,例如User.where(:user_id.in => @project.follower_ids)
(假设该数组称为follower_ids
)来获取所有用户及其姓名;)create an embedded document which holds all followers with their user_id and their username so you won't have to query the follower's usernames.
The benefits:
The downside:
If a user changes his name, you'll have to update all his "followships" but how often
do you change your name compared to how often you lookup your followed projects ;)
If you have many thousand followers per project you may reach the document limit of 16mb
user.rb
project.rb
follower.rb
How to work with it:
PS: If you want a simpler solution, you could just embedd an array of ObjectIDs (user_ids) in the project and use the atomic updates
$addToSet
and$pullAll
to add/remove a follower. But you'd need an extra query likeUser.where(:user_id.in => @project.follower_ids)
(assuming the array is calledfollower_ids
) to grab all users and their names ;)