Daha iyi:
Person.includes(:friends).where( :friends => { :person_id => nil } )
HMT için temelde aynı şey, arkadaşsız bir kişinin de hiçbir kişisinin olmayacağına güveniyorsunuz:
Person.includes(:contacts).where( :contacts => { :person_id => nil } )
Güncelleme
has_one
Yorumlar hakkında bir soru var , bu yüzden sadece güncelleme. Buradaki hile includes()
, ilişkilendirmenin where
adını beklemektedir, ancak tablonun adını beklemektedir. Bir has_one
dernek genellikle tekil olarak ifade edilir, böylece değişir, ama where()
kısım olduğu gibi kalır. Yani eğer Person
sadece bir has_one :contact
ifadeniz:
Person.includes(:contact).where( :contacts => { :person_id => nil } )
Güncelleme 2
Birisi tersini sordu, insansız arkadaşlar. Aşağıda yorumladığım gibi, bu aslında son alanın (yukarıda: the :person_id
) gerçekten geri döndüğünüz modelle ilgili olması gerekmediğini, sadece birleştirme tablosunda bir alan olması gerektiğini fark etmemi sağladı . Hepsi öyle olacak, nil
böylece herhangi biri olabilir. Bu, yukarıdakilere daha basit bir çözüm sağlar:
Person.includes(:contacts).where( :contacts => { :id => nil } )
Ve daha sonra hiç kimseyle arkadaşlarınızı geri getirmek için bunu değiştirmek daha da kolaylaşıyor, sadece öndeki sınıfı değiştiriyorsunuz:
Friend.includes(:contacts).where( :contacts => { :id => nil } )
Güncelleme 3 - Raylar 5
Mükemmel Rails 5 çözümü için @ Johnson sayesinde (aşağıdaki cevabı için ona + 1'ler verin), left_outer_joins
ilişkilendirmeyi yüklemekten kaçınmak için kullanabilirsiniz :
Person.left_outer_joins(:contacts).where( contacts: { id: nil } )
Buraya ekledim, böylece insanlar bulacak, ama bunun için + 1'leri hak ediyor. Harika bir ek!
Güncelleme 4 - Raylar 6.1
Yaklaşan 6.1'de bunu yapabileceğinizi işaret ettiği için Tim Park'a teşekkürler :
Person.where.missing(:contacts)
Sayesinde yazı o da bağlantılı.