4

我试图弄清楚如何为我正在处理的网站布局我的数据库。这是我的模型:

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 进行编码的方法的观点?

提前致谢!

4

2 回答 2

9

是否可以在 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
=> [#<Item name: "chocolate", _id: 4b44cc6c271a466269000001>]

>> i.fans
=> [#<User name: "emily", liked_item_ids: [4b44cc6c271a466269000001], _id: 4b44cc6c271a466269000002>]

不幸的是,你不能用这个设置做的是从Item关系的一边添加一个喜欢。但是,在 GitHub 上有一个关于为将要使用的关系创建正确反向的未解决问题many :in,在这种情况下,如下所示:

many :fans, :class_name => "User", :source => :liked_items

另一方面,如果有需要存储在 中的信息Like,例如用户喜欢该项目的日期,则目前没有办法对其进行建模。在这种情况下,理想的设置(不考虑 MongoMapper 现在支持的内容)将类似于您在问题中包含的内容。您需要所有三个模型,其中Like嵌入User模型和has_many :through关系以创建从Userto的链接Item。不幸的是,MongoMapper 对此的支持可能还很遥远。

如果您想鼓励在 MongoMapper 中支持此类行为,您可以在邮件列表中询问或在MongoMapper github 存储库上打开问题。

于 2010-01-06T18:04:52.497 回答
3

您可能想阅读 mongodb.org 上的文档“嵌入与参考”:http ://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-Embedvs.Reference

于 2010-01-20T17:40:10.053 回答