2011-03-16 11 views
12
class Person < ActiveRecord::Base 
    has_many :pets 

    scope :with_dog, join(:pets).where("pets.type = 'Dog'") 
    scope :without_pets ??????????????????????????????????? 
end 

class Pet < ActiveRecord::Base 
    belongs_to :people 
end 

मैं उस व्यक्ति मॉडल को एक दायरा जोड़ना चाहता हूं जो पालतू जानवरों को लौटाता है। कोई विचार? मुझे लगता है कि यह स्पष्ट है, लेकिन यह इस समय मुझसे बच रहा है। इस तरहरेल में कोई संबंधित रिकॉर्ड के साथ रिकॉर्ड ढूंढना 3

उत्तर

8

कोशिश कुछ:

Person.joins('left outer join pets on persons.id=pets.person_id'). 
     select('persons.*,pets.id'). 
     where('pets.id is null') 

मैं इसे परीक्षण नहीं किया है, लेकिन यह काम करना चाहिए।

विचार यह है कि हम बाएं बाहरी शामिल हो रहे हैं, इसलिए पालतू जानवरों के खेतों में प्रत्येक व्यक्ति के लिए शून्य नहीं होगा जिसमें पालतू जानवर नहीं हैं। join() एक स्ट्रिंग पास होने पर आपको ActiveRecord केवल पढ़ने-योग्य ऑब्जेक्ट्स लौटने के बाद से :readonly => false शामिल होने की आवश्यकता होगी।

+0

परिणामस्वरूप एसक्यूएल कि विफल रहता है: यहाँ एक कोड का उपयोग मैं का एक रूपांतरित संस्करण है। व्यक्तियों का चयन करें *, से 'छोड़ दिया persons' बाहरी pets.id पालतू जानवर में शामिल होने के जहां persons.id = pets.person_id जहां' persons'। 'हटाया गया' = 0 और (pet.id शून्य है) – Shagymoe

+0

ओह! मैं उसमें शामिल हो गया। यह होना चाहिए ... ... people.id = pets.person_id ", नहीं" ... जहां person.id = ... "। –

+0

क्या आपको चुनिंदा ('व्यक्तियों। *, Pet.id') में ", pet.id" की आवश्यकता है? इसमें व्यक्तियों के साथ टकराव करने की क्षमता है। जब तक आप इस तरह के कॉलम को उपनाम नहीं देते हैं: चुनें ('व्यक्तियों। *, Pet.id के रूप में pet.id') – mkirk

0

इम यकीन नहीं करता है, तो अपने पालतू मॉडल एक व्यक्ति आईडी है, लेकिन शायद इस प्रयास आप किसी भी तरह मदद करता है

scope :with_dog, joins(:pets).where("pets.type = 'Dog'") 
scope :without_pets, joins(:pets).where("pets.person_id != persons.id") 

अद्यतन: से 'में शामिल होने' 'मिलती है' के लिए क्वेरी विधि नाम सही किया।

5

मार्क वेस्टलिंग का जवाब सही है। बाहरी जुड़ाव जाने का सही तरीका है। एक आंतरिक जुड़ाव (जो जोड़ता है जो उत्पन्न करता है यदि आप इसे किसी एसोसिएशन का नाम/प्रतीक पास करते हैं, न कि स्वयं का एसक्यूएल) काम नहीं करेगा, क्योंकि इसमें ऐसे लोगों को शामिल नहीं किया जाएगा जिनके पास पालतू जानवर नहीं है।

यहाँ यह एक गुंजाइश के रूप में लिखा है: (। यदि वह काम नहीं करता है, 'लोगों' के साथ 'व्यक्ति' की जगह की कोशिश - मुझे यकीन है कि क्या आपके तालिका नाम है नहीं कर रहा हूँ)

scope :without_pets, joins("left outer join pets on pets.person_id = persons.id").where("pets.id is null") 

21
scope :without_pets, lambda { includes(:pets).where('pets.id' => nil) } 
+0

हालांकि बाएं बाहरी जॉइन 'शामिल' का उद्देश्य नहीं है, यह संयोजन के साथ है एक प्रश्न का परिणाम बाएं बाहरी जॉइन में होगा। – lulalala

+2

उद्देश्य के बावजूद यह काम करता है। स्वीकार्य उत्तर से कम हस्तलिखित एसक्यूएल = मुझे लगता है कि यह बेहतर है। –

1

संबंधित रिकॉर्ड के बिना रिकॉर्ड खोजने के लिए आपको एक बाएं बाहरी जॉइन का उपयोग करना होगा।

scope :without_pets, joins('LEFT OUTER JOIN pets ON people.id = pets.person_id').group('people.id').having('count(pets.id) = 0') 
संबंधित मुद्दे