Bu soruyu sadece has_many açısından değil, kendine referans veren çağrışım perspektifinden yanıtlamak istiyorum: perspektif aracılığıyla.
Diyelim ki kontakları olan bir CRM'miz var. Kişilerin diğer kişilerle ilişkileri olacaktır, ancak iki farklı model arasında bir ilişki oluşturmak yerine, aynı modelin iki örneği arasında bir ilişki oluşturacağız. Bir kişinin birçok arkadaşı olabilir ve diğer birçok kişi tarafından arkadaş olabilir, bu yüzden çoka çok bir ilişki oluşturmamız gerekecek.
Bir RDBMS ve ActiveRecord kullanıyorsak, has_many: through kullanırız. Bu nedenle, Arkadaşlık gibi bir birleştirme modeli oluşturmamız gerekir. Bu model iki alana sahip olacaktır, bir arkadaş ekleyen mevcut kişiyi temsil eden bir kişi_kimliği ve arkadaşlık edilen kullanıcıyı temsil eden bir arkadaş kimliği.
Ancak MongoDB ve Mongoid kullanıyoruz. Yukarıda belirtildiği gibi, Mongoid has_many: through veya eşdeğer bir özelliğe sahip değildir. MongoDB ile o kadar kullanışlı olmaz çünkü birleştirme sorgularını desteklemez. Bu nedenle, MongoDB gibi RDBMS olmayan bir veritabanında çok-çok ilişkisini modellemek için, her iki tarafta bir dizi 'yabancı' anahtar içeren bir alan kullanırsınız.
class Contact
include Mongoid::Document
has_and_belongs_to_many :practices
end
class Practice
include Mongoid::Document
has_and_belongs_to_many :contacts
end
Belgelerin belirttiği gibi:
Ters belgelerin temel belgeden ayrı bir koleksiyonda depolandığı pek çok ilişkiye, Mongoid'in has_and_belongs_to_many makrosu kullanılarak tanımlanır. Bu, Active Record'a benzer bir davranış sergiler, ancak birleştirme koleksiyonuna gerek yoktur, yabancı anahtar kimlikleri, ilişkinin her iki tarafında diziler olarak depolanır.
Bu nitelikteki bir ilişkiyi tanımlarken, her belge kendi koleksiyonunda saklanır ve her belge, bir dizi biçiminde diğerine bir "yabancı anahtar" referansı içerir.
# the contact document
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"practice_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
}
# the practice document
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"contact_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
}
Şimdi MongoDB'de kendi kendine referans veren bir Dernek için birkaç seçeneğiniz var.
has_many :related_contacts, :class_name => 'Contact', :inverse_of => :parent_contact
belongs_to :parent_contact, :class_name => 'Contact', :inverse_of => :related_contacts
İlgili kişiler ve çok sayıda olan ve birçok uygulamaya ait olan kişiler arasındaki fark nedir? Büyük farklılık! Biri, iki varlık arasındaki bir ilişkidir. Diğeri bir öz referanstır.