【问题标题】:Mongoid: How to implement a relationship between embedded documents?Mongoid:如何实现嵌入文档之间的关系?
【发布时间】:2013-04-24 22:11:05
【问题描述】:

我有一个父文档并且我想要两种不同类型的嵌入文档:一种作为父文档,另一种作为具有可选父文档的子文档。例如:

class ParentDoc
  include Mongoid::Document
  embeds_many :special_docs
  embeds_many :special_doc_groupings
end

class SpecialDoc
  include Mongoid::Document
  embedded_in :parent_doc
  belongs_to :special_doc_groupings
end

class SpecialDocGrouping
  include Mongoid::Document
  embedded_in :parent_doc
  has_many :special_docs
end

在本例中,SpecialDocs 和 SpecialDocGroupings 可以不存在关系,也可以有父子关系。

但是,这是一个无效的 Mongoid 关联,因为我们收到此错误:

Mongoid::Errors::MixedRelations:

问题: 由于嵌入了 SpecialDoc,因此不允许通过关系关联从 SpecialDocGrouping 文档中引用 (n) SpecialDoc 文档。

总结: 为了从 SpecialDocGrouping 正确访问一个(n)SpecialDoc,引用需要通过 SpecialDoc 的根文档。在一个简单的情况下,这将需要 Mongoid 为根存储一个额外的外键,在更复杂的情况下,SpecialDoc 是多个级别的深度,则需要为层次结构中的每个父级存储一个键。

分辨率: 考虑不嵌入 SpecialDoc,或者在应用程序代码中以自定义方式进行密钥存储和访问。

我认为我尝试创建的关联类型没有任何问题,除了 Mongoid 不支持它。

我如何自己实现这种类型的关联?

【问题讨论】:

  • 是的,你的权利,你不能在 mongoid 中定义这种类型的关联,关于你的问题`我自己实现这种类型的关联?`在 activerecord 关联中听说过extend,你可以实现类似的东西如果 mongoid 也支持这种类型的东西,或者使用扩展(我会检查并让你知道这个)干杯

标签: ruby mongoid


【解决方案1】:

关联无效,因为当您引用嵌入式模型时,Mongoid 不会将父键存储为外键。 这意味着如果您有:

Class Parent        
   embeds_many :children
end 

Class Child
   embedded_in :parent
end

您不能引用仅存储其外键的子文档,但您需要存储所有父键,直到您到达根目录。 在这种情况下,根由第一个父级表示,您需要存储 2 个键。

您可以手动完成此操作,并毫无问题地创建这种类型的关联。

您的情况有点不同(而且更简单),因为您想在嵌入同一父项的两个模型之间创建关联。这意味着理论上您不需要存储父键,因为模型共享相同的根。 Mongoid 不处理这种情况,因此您需要手动创建关联规则和方法。

Class Bar
  embeds_many :beers
  embeds_many :glasses
end

Class Beer
  embedded_in :bar
  # Manual has_many :glasses association
  def parent
     self.bar
  end

  def glasses
     parent.glasses.where(:beer_id => self.id)
  end

end

Class Glass
   embedded_in :bar
   # Manual belongs_to :beer association
   field :beer_id, type: Moped::BSON::ObjectId
   def parent
      self.bar
   end

   def beer
      parent.beers.find(self.beer_id)
   end
end

(代码未测试)

【讨论】:

  • 我不太明白你的解释,但你的解决方案与我想出的几乎相同。我也喜欢你的例子名字。 =]
  • 如果您要关联的嵌入文档具有不同的父文档,您将如何在 Mongoid 中执行此操作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
相关资源
最近更新 更多