2013-08-14 6 views
36

मैं ऐसे ऐप पर काम कर रहा हूं जो सदस्यों को एक सर्वेक्षण करने की अनुमति देता है (सदस्य के पास प्रतिक्रिया के साथ कई रिश्ते हैं)। प्रतिक्रिया सदस्य_आईडी, question_id, और उनके उत्तर रखती है।रेल 'सक्रिय' के साथ सक्रिय रिकॉर्ड पूछताछ एसोसिएशन

सर्वेक्षण सभी या कुछ भी सबमिट नहीं किया गया है, इसलिए यदि उस सदस्य के लिए प्रतिक्रिया तालिका में कोई रिकॉर्ड हैं तो उन्होंने सर्वेक्षण पूरा कर लिया है।

मेरा सवाल है, मैं नीचे दी गई क्वेरी को फिर से कैसे लिखूं ताकि यह वास्तव में काम करे? एसक्यूएल में यह EXISTS कीवर्ड के लिए एक प्रमुख उम्मीदवार होगा।

def surveys_completed 
    members.where(responses: !nil).count 
end 

उत्तर

82

आप includes उपयोग कर सकते हैं और उसके बाद का परीक्षण करता है, तो संबंधित प्रतिक्रिया (रों) इस तरह मौजूद है:

def surveys_completed 
    members.joins(:responses) 
end 

समाधान:

def surveys_completed 
    members.includes(:responses).where('responses.id IS NOT NULL') 
end 

यहाँ एक वैकल्पिक, joins साथ है रेल का उपयोग 4:

def surveys_completed 
    members.includes(:responses).where.not(responses: { id: nil }) 
end 

इसी प्रकार के प्रश्न:

+1

पहला विकल्प इस बहिष्करण नोटिस http://pastebin.com/KbsNiqLy दिया। दूसरे ने 68 बार एक ही रिकॉर्ड लौटाए क्योंकि उनके 68 प्रश्न हैं इसलिए मैंने इसे इस तरह संशोधित किया: members.joins (: प्रतिक्रियाएं) .uniq.count – Lee

+2

बहिष्करण नोटिस से बचा नहीं जा सकता है क्योंकि हमें एक स्ट्रिंग टाइप करने की आवश्यकता है कहते हैं "पूर्ण नहीं है" (जब तक आप रेल 4 का उपयोग नहीं करते हैं तब तक शुद्ध ActiveRecord में इसका अनुवाद करना संभव नहीं है)। मैं एक सेकंड @lee – MrYoshiji

+0

में तीसरे स्थान पर रखूंगा, मैंने बहिष्करण नोटिस में और अधिक देखा, और यह किया: members.includes (: प्रतिक्रियाएं)। कहीं भी ('प्रतिक्रियाएं। नल नहीं है')। संदर्भ (प्रतिक्रियाएं)। गिनती है और यह भी काम करता है। तो अब यह एक सवाल है कि "सर्वश्रेष्ठ" तरीका – Lee

6

आप एसक्यूएल EXISTS कीवर्ड सुरुचिपूर्ण रेल-ish तरीके से Where Exists मणि का उपयोग कर का उपयोग कर सकते हैं:

members.where_exists(:responses).count 
बेशक

आप के रूप में अच्छी तरह से कच्चे एसक्यूएल का उपयोग कर सकते हैं:

members.where("EXISTS" \ 
    "(SELECT 1 FROM responses WHERE responses.member_id = members.id)"). 
    count 
+1

गिनती अन्य उत्तर SQL का उपयोग नहीं करेगा जो मौजूदा कीवर्ड इस तरह से अधिक प्रदर्शन करने वाला होगा! – rept

1

तुम भी एक का उपयोग कर सकते सबक्वायरी:

members.where(id: Response.select(:member_id)) 

के साथ कुछ की तुलना मेंयह संबंधित मॉडल लोड नहीं करेगा (यदि आपको उनकी आवश्यकता नहीं है तो एक प्रदर्शन लाभ है)।

संबंधित मुद्दे