2013-03-29 48 views
0

假設我有一個名爲Foo的mongoid模型,嵌入了許多Bar。使用Mongoid的自引用嵌入式文檔

class Foo 
    ... 
    embeds_many :bar 
    ... 
end 

class Bar 
    ... 
    embedded_in :foo 
    ... 
end 

我想創建一個關係,其中Bar鏈接到它自己。該關係將始終涉及嵌入在同一個Foo文檔中的兩個文檔。在調用這種關係時,我似乎無法做到這一點。我曾嘗試

belongs_to :discovered_by, :class_name => 'Bar' 

has_one :discovered_by, :class_name => 'Bar' 

雖然discovered_by ID是酒吧文檔中設置和指向當我嘗試做其他酒吧文檔下面我得到零(假設第一富的第一條具有discovered_by_id集)

Foo.first.bars.first.discovered_by 

這將爲零,儘管具有ID設置doucment總是返回。任何想法爲什麼會發生這種情況?謝謝你的幫助。

回答

1

cannot have references to embedded models - 即使它們都嵌入在同一個文檔中。如果你正確配置關係

belongs_to :discovered_by, :class_name => 'Bar', inverse_of: :discovered 
has_one :discovered, :class_name => 'Bar', inverse_of: :discovered_by 

Mongoid會提出Mongoid::Errors::MixedRelations異常。也許你可以重新考慮嵌入這些對象是否仍然是最佳選擇。解決方法是隻存儲id並查詢父對象:

class Bar 
    include Mongoid::Document 
    embedded_in :foo 
    field :discovered_by_id, type: Moped::BSON::ObjectId 

    def discovered_by 
     foo.bars.find(discovered_by_id) if discovered_by_id 
    end 

    def discovered_by=(bar) 
     self.discovered_by_id = bar.id 
    end 
end 
+0

我想我將不得不按照您的解決方案中的建議存儲該ID。不理想,但它服務我的目的。有人說你有關重新考慮嵌入式文檔的評論很有趣。它是否違背了「mongo方式」的做法來考慮嵌入在相同父文檔中的兩個文檔?我想這將符合Mongoid的實現。 – Stewart

+1

是的,通常引用嵌入式文檔是一個壞主意。部分從技術角度來看(使用關係的對象必須知道每個嵌入模型層的父對象)和設計觀點(嵌入對象只能通過父對象訪問)。但是,您的示例有點像邊緣案例:您肯定知道您所指的記錄的父對象('foo')。我可能會採用解決方法 - 唯一的缺點是你不能使用標準的'belongs_to'和'has_one'助手。 – 2013-03-30 08:31:47