我试图弄清楚如何为我正在处理的网站布置我的数据库.这是我的模特:
class User include MongoMapper::Document // keys here many :items many :likes end class Item include MongoMapper::Document key :name, String, :required => true many :likes end class Like include MongoMapper::EmbeddedDocument key :user_id, String, :required => true end
我相信Like
应该嵌入某个地方,但我很难选择一个,因为我想要摆脱它的功能.
user = User.first user.likes // should print out all the Items he liked item = Item.first item.likes // so I can count how many people like that item
虽然使用EmbeddedDocument时会出现问题,但是您会丢失find
其他有用的方法,并且不能将它嵌入到两个模型中.所以只有它Item
,我需要运行它(但不能):
item = Item.first item.likes.find_by_user_id(User.first._id)
find_by_user_id
将抛出未定义的方法.所以如果我把它嵌入我的中User
,我仍然无法做到这一点.
likes = Like.all // will throw undefined `all`
所以我开始考虑这样做:
class Like include MongoMapper::Document key :user_id, String, :required => true key :item_id, String, :required => true belongs_to :user belongs_to :item end
但这似乎我仍在尝试用旧的MySQL方式做事.有人能用最有可能的方式给我一点用MongoMapper来编码吗?
提前致谢!
是否可以在MongoMapper中对此进行建模取决于是否需要存储在Like
模型中的数据.如果在您的示例中没有与Like
模型关联的任何数据,则有一种方法.对MongoMapper的最新更新增加了对多对多关系的支持,尽管它仍处于早期阶段.
您可以像这样创建模型:
class User include MongoMapper::Document key :name, String, :required => true key :liked_item_ids, Array many :liked_items, :in => :liked_item_ids, :class_name => "Item" end class Item include MongoMapper::Document key :name, String, :required => true many :fans, :class_name => "User", :foreign_key => :liked_item_ids end
然后你可以这样做:
>> u = User.new( :name => 'emily' ) >> i = Item.new( :name => 'chocolate' ) >> u.liked_items << i >> u.save >> u.liked_items => [#- ] >> i.fans => [#
]
不幸的是,你不能用这个设置做的是从Item
关系的一侧添加一个类似的东西.但是,GitHub上有一个关于为many :in
将要使用的关系创建正确反向的问题,在本例中,如下所示:
many :fans, :class_name => "User", :source => :liked_items
另一方面,如果存在需要存储的信息Like
,例如用户喜欢该项目的日期,则目前没有办法对其进行建模.在这种情况下,理想的设置(忽略MongoMapper现在支持的内容)与您在问题中包含的内容类似.你需要的所有三个型号,与Like
嵌入User
模型和has_many :through
从创建链接关系User
来Item
.不幸的是,在MongoMapper中对此的支持可能相当遥远.
如果你想在MongoMapper中鼓励支持这样的行为,你可以在邮件列表上询问它或在MongoMapper github存储库上打开一个问题.