Anlama: has_one / has_many - Rails kaynak seçeneği


184

Lütfen dernek :sourceseçeneğini anlamada bana yardım et has_one/has_many :through. Rails API açıklaması bana çok az mantıklı geliyor.

"Belirtir kaynak dernek adı kullandığı has_many :through => :queries. Ad dernek anlaşılmaktadır edilemezse Sadece kullanabilirsiniz. has_many :subscribers, :through => :subscriptionsYa arayacaktır :subscribersveya :subscriberüzerinde Subscriptionbir sürece :sourceverilir."

Yanıtlar:


238

Bazen, farklı ilişkilendirmeler için farklı adlar kullanmak istersiniz. Modeldeki bir ilişkilendirme için kullanmak istediğiniz ad, modeldeki ilişkilendirmeyle aynı değilse, belirtmek için :throughkullanabilirsiniz :source.

Yukarıdaki paragrafın dokümanlardakinden çok daha net olduğunu düşünmüyorum, işte bir örnek. Diyelim ki üç modelimiz var Pet, Dogve Dog::Breed.

class Pet < ActiveRecord::Base
  has_many :dogs
end

class Dog < ActiveRecord::Base
  belongs_to :pet
  has_many :breeds
end

class Dog::Breed < ActiveRecord::Base
  belongs_to :dog
end

Bu durumda, güzel ve kullanışlı bir dernek olarak Dog::Breederişmek istediğimiz için ad alanını seçtik Dog.find(123).breeds.

Şimdi, şimdi bir has_many :dog_breeds, :through => :dogsilişki kurmak istiyorsak Pet, aniden bir sorunumuz var. Rails bir :dog_breedsilişkilendirme bulamaz Dog, bu nedenle Rails hangi Dog ilişkilendirmeyi kullanmak istediğinizi bilemez . Şunu girin :source:

class Pet < ActiveRecord::Base
  has_many :dogs
  has_many :dog_breeds, :through => :dogs, :source => :breeds
end

İle :sourcebizler söyleme etmek Raylar, adında bir dernek aramaya :breedsüzerine Dogmodelin (bunu engellemek için kullanılan model olarak :dogso ve kullanım).


2
Sanırım son sınıf Hayvanınız için sınıf Pet olarak adlandırıldınız, sadece inandığım bir yazım hatası demek istediniz.
Kamilski81

3
Yukarıdaki örnekte, ilişki altında olmalıdır Dogolmak has_many :breedyerine :breedsve sonra :sourceolmak :breed, yerine, model adı tekil temsil etmek için :breedshangi tablo adını gösterir? Örneğin has_many :dog_breeds, :through => :dogs, :source => :breed( ssonek yok :breed)?
LazerSharks

1
Bunu test ettim. tekil, hiçbir ssonek:source =>
Anwar

"Bu durumda, Dog :: Breed'i adlandırmayı seçtik, çünkü Dog.find (123) .breeds'e güzel ve kullanışlı bir dernek olarak erişmek istiyoruz." Bunun için bir ad alanına ihtiyacınız yok değil mi?
Jwan622

201

Bu örneği genişletmeme izin verin:

class User
  has_many :subscriptions
  has_many :newsletters, :through => :subscriptions
end

class Newsletter
  has_many :subscriptions
  has_many :users, :through => :subscriptions
end

class Subscription
  belongs_to :newsletter
  belongs_to :user
end

Bu kodla, Newsletter.find(id).usersbülten abonelerinin bir listesini almak gibi bir şey yapabilirsiniz . Ancak daha açık olmak ve Newsletter.find(id).subscribersbunun yerine yazabilmek istiyorsanız, Bülten sınıfını şu şekilde değiştirmeniz gerekir:

class Newsletter
  has_many :subscriptions
  has_many :subscribers, :through => :subscriptions, :source => :user
end

usersİlişkilendirmeyi olarak yeniden adlandırıyorsunuz subscribers. Eğer girmezseniz :source, Raylar adında bir dernek arayacaktır subscriberAbonelik sınıfında. userAbonelerin listesini yapmak için Abonelik sınıfındaki ilişkilendirmeyi kullanmasını söylemelisiniz .


2
tekil model isimlerinin :source =>çoğul değil de kullanılması gerektiğini unutmayın . Yani, :usersyanlış, :userdoğru
Anwar

Bu en iyi cevap !, sadece bu bölümü vurgulayayım: "Abonelerle kullanıcı ilişkilendirmesini yeniden adlandırıyorsunuz.: Kaynağını sağlamazsanız, Rails Abonelik sınıfında abone adı verilen bir ilişki arar."
Brian Joseph Spinos

11

En basit cevap:

Tablodaki ortadaki ilişkinin adıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.