2013-04-24 7 views
6

Tôi có một tình huống mà tôi có tài liệu gốc và tôi muốn có hai loại tài liệu nhúng khác nhau: một là cha mẹ và một tài liệu khác làm con với cha mẹ tùy chọn. Ví dụ:Mongoid: Cách triển khai mối quan hệ giữa các tài liệu được nhúng?

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 

Trong ví dụ này, SpecialDocs và SpecialDocGroupings có thể tồn tại mà không có mối quan hệ hoặc có thể có mối quan hệ cha-con.

Tuy nhiên, đây là một hiệp hội Mongoid không hợp lệ bởi vì chúng tôi nhận được lỗi này:

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.

tôi không thấy bất cứ điều gì sai trái với các loại hiệp hội mà tôi đang cố gắng để tạo ra, bên cạnh thực tế là nó là không được hỗ trợ bởi Mongoid.

Làm cách nào để tự mình triển khai loại kết hợp này?

+0

yaa đúng của bạn, bạn không thể xác định loại như vậy của hiệp hội trong mongoid liên quan đến câu hỏi của bạn 'Tôi thực hiện loại hình này của hiệp hội bản thân mình?' Cũng đã nghe [mở rộng] (http://guides.rubyonrails.org/association_basics.html#extend) trong hiệp hội activerecord tốt, bạn có thể thực hiện một cái gì đó như thế hoặc sử dụng mở rộng nếu mongoid quá hỗ trợ một cái gì đó loại đó (tôi sẽ kiểm tra và cho bạn biết abt này) Chúc mừng – Viren

Trả lời

10

Kết hợp không hợp lệ vì khi bạn tham khảo mô hình nhúng Mongoid không lưu trữ khóa chính làm khóa ngoài. Điều này có nghĩa rằng nếu bạn có:

Class Parent   
    embeds_many :children 
end 

Class Child 
    embedded_in :parent 
end 

Bạn không thể tham khảo tài liệu lưu trữ Child chỉ bàn phím ngoài của nó, nhưng bạn cần phải lưu trữ tất cả các phím cha mẹ cho đến khi bạn đạt được mục gốc. Trong trường hợp này gốc được đại diện bởi cha mẹ đầu tiên và bạn cần lưu trữ 2 khóa.

Bạn có thể thực hiện việc này theo cách thủ công và tạo loại liên kết này mà không gặp bất kỳ sự cố nào.

Trường hợp của bạn hơi khác một chút (và dễ dàng hơn) vì bạn muốn tạo liên kết giữa hai mô hình được nhúng trong cùng một cấp độ gốc. Điều đó có nghĩa về mặt lý thuyết bạn không cần lưu trữ khóa cha bởi vì các mô hình chia sẻ cùng một gốc. Mongoid không xử lý kịch bản này, vì vậy bạn cần phải tạo thủ công các quy tắc và phương thức liên kết của mình.

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 

(mã không được kiểm tra)

+1

Tôi đã không hoàn toàn hiểu lời giải thích của bạn, nhưng giải pháp của bạn khá giống với những gì tôi nghĩ ra. Tôi cũng thích tên ví dụ của bạn. =] – Andrew

+0

Bạn sẽ làm như thế nào trong Mongoid nếu các tài liệu được nhúng mà bạn muốn liên kết có các tài liệu gốc khác nhau? – elsurudo