Neyin ne has_many :through
olduğunu ve ne zaman (ve nasıl) kullanılacağını anlamaya çalışıyorum . Ancak, anlamıyorum. Beginning Rails 3 okuyorum ve Googling'i denedim, ancak anlayamıyorum.
Neyin ne has_many :through
olduğunu ve ne zaman (ve nasıl) kullanılacağını anlamaya çalışıyorum . Ancak, anlamıyorum. Beginning Rails 3 okuyorum ve Googling'i denedim, ancak anlayamıyorum.
Yanıtlar:
Diyelim ki iki modeliniz var: User
ve Group
.
Kullanıcıların gruplara üye olmasını istiyorsanız, bunun gibi bir şey yapabilirsiniz:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
İlişkilendirme ile ilgili ek meta verileri izlemek isterseniz ne olur? Örneğin, kullanıcı gruba katıldığında veya belki de kullanıcının gruptaki rolü nedir?
Bu, ilişkilendirmeyi birinci sınıf bir nesne yaptığınız yerdir:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
Bu, yeni bir tablo sunar ve group_id
kullanıcının tablosundaki sütunu kaldırır .
Bu kodla ilgili sorun, kullanıcı sınıfını kullandığınız her yerde güncellemeniz ve değiştirmeniz gerektiğidir:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
Bu tür bir kod berbattır ve bu gibi değişikliklerin yapılmasını acı verici hale getirir.
has_many :through
size her iki dünyanın da en iyisini verir:
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
Artık buna normal bir davranış gibi davranabilir has_many
, ancak ihtiyaç duyduğunuzda ilişkilendirme modelinden yararlanabilirsiniz.
Bunu ile de yapabileceğinizi unutmayın has_one
.
Düzenleme: Bir gruba kullanıcı eklemeyi kolaylaştırma
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user.groups << group
? Yoksa her şey bu dernek tarafından mı ele alınır?
Şu modellere sahip olduğunuzu varsayalım:
Car
Engine
Piston
Bir araba has_one :engine
Bir motor belongs_to :car
Bir motorhas_many :pistons
Pistonbelongs_to :engine
Araba has_many :pistons, through: :engine
Pistonuhas_one :car, through: :engine
Esasen başka modele model ilişkisi devrederek, bu yüzden yerine çağrıya sahip car.engine.pistons
, sadece yapabilirsinizcar.pistons
has_many :through
ve has_and_belongs_to_many
ilişkiler yoluyla işlev birleştirme tablosunda diğer tabloları arasındaki ilişkiyi temsil eden bir ara tablodur. Bir JOIN sorgusundan farklı olarak, veriler aslında bir tabloda saklanır.
İle has_and_belongs_to_many
, birincil anahtara ihtiyacınız yoktur ve kayıtlara bir ActiveRecord modeli yerine ActiveRecord ilişkileri aracılığıyla erişirsiniz. İki modeli çoka çok ilişkisine bağlamak istediğinizde genellikle HABTM kullanırsınız.
has_many :through
Birleştirme tablosuyla bir Rails modeli olarak etkileşim kurmak istediğinizde, birincil anahtarlarla ve birleştirilen verilere özel sütunlar ekleme becerisiyle birlikte bir ilişki kullanırsınız. İkincisi, birleştirilen satırlarla ilgili olan, ancak gerçekten ilgili modellere ait olmayan veriler için özellikle önemlidir - örneğin, birleştirilmiş satırdaki alanlardan türetilen hesaplanmış bir değeri depolamak.
In Active kayıt Dernekler A Guide , öneri okur:
En basit kural, ilişki modeliyle bağımsız bir varlık olarak çalışmanız gerekiyorsa, has_many: ilişki yoluyla kurmanız gerektiğidir. İlişki modeliyle herhangi bir şey yapmanız gerekmiyorsa, has_and_belongs_to_many ilişkisi kurmak daha basit olabilir (ancak veritabanında birleştirme tablosunu oluşturmayı hatırlamanız gerekecektir).
Birleştirme modelinde doğrulamalara, geri aramalara veya ekstra özniteliklere ihtiyacınız varsa, has_many: through kullanmalısınız.
user
Grubu eklemek için modele bir yöntem ekleyeceğim yer burasıdır . Az önce yaptığım düzenleme gibi bir şey. Bu yardımcı olur umarım.