2013-04-24 12 views
6

Ich habe eine Situation, in der ich ein Elterndokument habe und ich möchte zwei verschiedene Arten von eingebetteten Dokumenten haben: eins als ein Elternteil und ein anderes als Kind mit einem optionalen Elternteil. Zum Beispiel:Mongoid: Wie implementiert man eine Beziehung zwischen eingebetteten Dokumenten?

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 

In diesem Beispiel SpecialDocs und SpecialDocGroupings können ohne Beziehung existieren, oder gegebenenfalls eine Eltern-Kind-Beziehung haben können.

Dies ist jedoch ein ungültiger Mongoid Verein, weil wir diesen Fehler:

Mongoid::Errors::MixedRelations:

Problem: Referencing a(n) SpecialDoc document from the SpecialDocGrouping document via a relational association is not allowed since the SpecialDoc is embedded.

Summary: In order to properly access a(n) SpecialDoc from SpecialDocGrouping the reference would need to go through the root document of SpecialDoc. In a simple case this would require Mongoid to store an extra foreign key for the root, in more complex cases where SpecialDoc is multiple levels deep a key would need to be stored for each parent up the hierarchy.

Resolution: Consider not embedding SpecialDoc, or do the key storage and access in a custom manner in the application code.

ich nichts falsch mit der Art der Assoziation sehen, dass ich versuche, neben der Tatsache zu schaffen, dass es nicht von Mongoid unterstützt.

Wie kann ich diese Art der Verknüpfung selbst implementieren?

+0

Yaa rechten Sie diese Art von Vereinigung in mongoid in Bezug auf Ihre Frage definieren kippen 'ich diese Art von Vereinigung selbst implementieren?' Gut gehört hat [erweitern] (http://guides.rubyonrails.org/association_basics.html#extend) in activerecord association gut kann man sowas implementieren oder extendieren, wenn mongoid auch sowas unterstützt (ich überprüfe es und lasse es dich wissen) Prost – Viren

Antwort

10

Die Zuordnung ist nicht gültig, da Mongoid den übergeordneten Schlüssel nicht als Fremdschlüssel speichert, wenn Sie auf das eingebettete Modell verweisen. Das bedeutet, dass, wenn Sie:

Class Parent   
    embeds_many :children 
end 

Class Child 
    embedded_in :parent 
end 

Sie nicht Kinder Dokument der Fremdschlüssel zu speichern Referenz kann nur, aber Sie alle Eltern Schlüssel speichern müssen, bis Sie die Wurzel erreichen. In diesem Fall wird der Stamm durch den ersten Elternteil repräsentiert und Sie müssen 2 Schlüssel speichern.

Sie können dies manuell durchführen und diese Art der Zuordnung problemlos erstellen.

Ihr Fall ist ein bisschen anders (und einfacher), weil Sie die Verbindung zwischen zwei Modellen erstellen möchten, die im gleichen Elternteil eingebettet sind. Das bedeutet theoretisch, dass Sie den übergeordneten Schlüssel nicht speichern müssen, da die Modelle denselben Stamm haben. Mongoid behandelt dieses Szenario nicht, daher müssen Sie Ihre Assoziationsregeln und Methoden manuell erstellen.

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 

(der Code nicht getestet)

+1

Ich habe Ihre Erklärung nicht ganz verstanden, aber Ihre Lösung ist ziemlich identisch mit dem, was ich mir ausgedacht habe. Ich mag auch deine Beispielnamen. =] – Andrew

+0

Wie würden Sie das in Mongoid machen, wenn die eingebetteten Dokumente, die Sie zuordnen möchten, andere übergeordnete Dokumente haben? – elsurudo

Verwandte Themen