Saya ingin menjawab pertanyaan ini dari perspektif asosiasi referensi sendiri, bukan hanya has_many: through perspektif.
Katakanlah kita memiliki CRM dengan kontak. Kontak akan memiliki hubungan dengan kontak lain, tetapi alih-alih membuat hubungan antara dua model yang berbeda, kita akan membuat hubungan antara dua contoh model yang sama. Kontak dapat memiliki banyak teman dan berteman dengan banyak kontak lainnya, jadi kita harus membuat hubungan banyak-ke-banyak.
Jika kita menggunakan RDBMS dan ActiveRecord, kita akan menggunakan has_many: through. Jadi kita perlu membuat model gabungan, seperti Persahabatan. Model ini akan memiliki dua bidang, contact_id yang mewakili kontak saat ini yang menambahkan teman dan friend_id yang mewakili pengguna yang sedang berteman.
Tapi kami menggunakan MongoDB dan Mongoid. Seperti yang dinyatakan di atas, Mongoid tidak memiliki has_many: through atau fitur yang setara. Ini tidak akan begitu berguna dengan MongoDB karena tidak mendukung kueri penggabungan. Oleh karena itu, untuk membuat model hubungan banyak-banyak dalam database non-RDBMS seperti MongoDB, Anda menggunakan kolom yang berisi larik kunci 'asing' di kedua sisinya.
class Contact
include Mongoid::Document
has_and_belongs_to_many :practices
end
class Practice
include Mongoid::Document
has_and_belongs_to_many :contacts
end
Seperti yang dinyatakan dalam dokumentasi:
Banyak ke banyak hubungan di mana dokumen invers disimpan dalam koleksi terpisah dari dokumen dasar ditentukan menggunakan makro has_and_belongs_to_many Mongoid. Ini menunjukkan perilaku yang mirip dengan Rekaman Aktif dengan pengecualian bahwa tidak diperlukan pengumpulan gabungan, id kunci asing disimpan sebagai array di kedua sisi relasi.
Saat mendefinisikan relasi seperti ini, setiap dokumen disimpan dalam koleksi masing-masing, dan setiap dokumen berisi referensi "kunci asing" satu sama lain dalam bentuk larik.
# the contact document
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"practice_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
}
# the practice document
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"contact_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
}
Sekarang untuk Asosiasi referensi mandiri di MongoDB, Anda memiliki beberapa opsi.
has_many :related_contacts, :class_name => 'Contact', :inverse_of => :parent_contact
belongs_to :parent_contact, :class_name => 'Contact', :inverse_of => :related_contacts
Apa perbedaan antara kontak terkait dan kontak memiliki banyak dan memiliki banyak praktik? Perbedaan besar! Salah satunya adalah hubungan antara dua entitas. Lainnya adalah referensi diri.