Mongoid将embeds_many和has_many嵌入到同一个模型中

时间:2013-02-24 16:47:10

标签: ruby-on-rails mongodb mongoid

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

  

故障/错误:        Mongoid ::错误:: MixedRelations:

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

推荐的角色是嵌入式的。

代码:

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

有解决方法吗?

1 个答案:

答案 0 :(得分:0)

由于Mongoid只能做一个或另一个,因此需要一个解决方法。这是一个(未经测试的)例子,希望能让你朝着正确的方向前进。

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

field :person_being_suggested_id, type: String

此属性可以存储其他Person对象的ID。在您的SuggestedPerson表单上,让我们假设我们的实例变量包含SuggestedPerson控制器中的所有人员(@persons = Person.all),并且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,并返回所有名称的列表。第二个示例仅返回为特定嵌入文档建议的人员的姓名。