【问题标题】:Mongoid embeds_many and has_many to the same modelMongoid embeds_many 和 has_many 到同一个模型
【发布时间】:2013-02-09 19:57:34
【问题描述】:

我有一个模型“Person”,它嵌入了多个“SuggestedPerson”。 SuggestedPerson 还引用另一个人(被建议的人)。所以 Person 需要 embed_many 和 has_many SuggestedPerson。问题是 Mongo 返回错误:

失败/错误: Mongoid::Errors::MixedRelations:

   Problem:
     Referencing a(n) SuggestedPerson document from the Person document via a relational association is not allowed since the

SuggestedPerson 已嵌入。

代码:

class Person
  embeds_many :suggested_persons, :class_name => "SuggestedPerson", :inverse_of => :person
  has_many :suggested_to_persons, :class_name => "SuggestedPerson", :inverse_of => :to_person
end

class SuggestedPerson
  embedded_in :person, :class_name => "Person", :inverse_of => :suggested_persons 
  belongs_to :to_person, :class_name => "Person", :inverse_of => :suggested_to_persons
end

有没有办法解决这个问题?

【问题讨论】:

  • 最快的方法是将关联更改为 has_many,但这是 hacky。
  • 是的,谢谢,我就是这么做的:/
  • 但我也想知道另一种解决方案不是破解...
  • 没有任何其他解决方案...嵌入文档不能被嵌入它的模型以外的任何其他模型引用...因为documentation 说:Documents that are embedded using the embeds_one macro are stored as a hash inside the parent in the parent's database collection. 所以它们是没有单独存储...因此无法引用。

标签: ruby-on-rails mongodb mongoid


【解决方案1】:

由于 Mongoid 只能做其中之一,因此需要一种解决方法。这是一个(未经测试的)示例,希望能让您朝着正确的方向前进。

如果您需要嵌入的 SuggestedPerson 对象来引用另一个 Person 对象(除了父对象),您可能需要在 SuggestedPerson 嵌入对象上创建一个字段,例如:

field :person_being_suggested_id, type: String

这个属性可以存储另一个Person对象的ID。在您的 SuggestedPerson 表单上,假设我们在 SuggestedPerson 控制器 (@persons = Person.all) 中有包含所有 Persons 的实例变量,并且 Persons 有一个 name 属性,这样我们就可以使用这个不错的方法从下拉列表中进行选择帮手:

<%= f.collection_select(:person_being_suggested_id, @persons, :id, :name, {prompt: ""}) %>

在您的 SuggestedPerson 模型中,您可以使用以下方法:

def suggested_persons_name
  Person.find_by(id: self.person_being_suggested_id).name
end

这样,当您使用 Person 类的实例时,您可以调用如下内容:

@person.suggested_persons.each do |person|
  p person.suggested_persons_name
end

或者说您正在使用 SuggestedPerson 类的实例:

@suggested_person.suggested_persons_name

第一个示例将遍历 Person 对象中所有嵌入的 SuggestedPersons,在每个对象上调用方法Suggested_persons_name 并返回所有名称的列表。第二个示例将只返回针对该特定嵌入文档建议的人的姓名。

【讨论】:

    猜你喜欢
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多