2011-11-22 12 views
8

इन मॉडलों के साथ:रेल और मैंगॉयड का उपयोग करके एसोसिएशन की "गिनती" द्वारा रिकॉर्ड कैसे प्राप्त कर सकते हैं?

Week.where(:proof.count.gt => 0) 

केवल सप्ताह कई सबूत है कि खोजने के लिए:

class Week 
    has_many :proofs 
end 
class Proof 
    belongs_to :week 
end 

मैं की तरह कुछ करना चाहते हैं।

Can rails scopes filter on the number of associated classes for a given field

लेकिन इस उदाहरण में, वहाँ वीक में proof_ids जैसी कोई विशेषता है के बाद से आईडी प्रमाणों के साथ जमा हो जाती है:

एक ही जवाब है कि इसका समाधान करने लगता है। यह उदाहरण के लिए काम नहीं करता है:

Week.where(:proof_ids.gt => 0) 

यह प्रश्न कैसे संभव है? संकल्पनात्मक रूप से सरल लेकिन मैं यह नहीं समझ सकता कि इसे मोंगो या मोंगोइड के साथ कैसे किया जाए।

Week.desc(:proofs.size) 

लेकिन यह भी काम नहीं करता:

इसी तरह, मैं जैसे उदाहरण के लिए सबूत की संख्या से ऑर्डर करने के लिए करना चाहते हैं।

मुझे एहसास है कि काउंटर कैश मेरे विशिष्ट प्रश्नों के लिए एक विकल्प है लेकिन मैं भी क्वेरी करने में सक्षम होना चाहता हूं।

किसी भी मदद के लिए अग्रिम धन्यवाद।

उत्तर

5

रेल के साथ (और counter_cache के बिना), तुम कर सकते हो:

class Week < ActiveRecord::Base 
    has_many :proofs 

    def self.by_proofs_size 
    sort_by { |week| week.proofs.size } 
    end 

    def self.with_at_least_n_proofs(n = 1) 
    select { |week| week.proofs.size >= n } 
    end 
end 

हालांकि उन कार्यों में से प्रत्येक के 2 प्रश्नों पैदा करता है, यह अब तक आदर्श से है।

प्रश्नों की जोड़ी दोहराया है (=> प्रत्येक ऑपरेशन के लिए 4 प्रश्नों) के साथ स्कोप (बग?):

scope :with_at_least_n_proofs, -> (n = 1) { select { |w| w.proofs.size >= n } } 
scope :by_proofs_size, -> { sort_by { |w| w.proofs.size } } 

आदर्श शायद उपयोग करने के लिए है counter_cache

scope :with_at_least_n_proofs, -> (n = 1) { where('proofs_count >= ?', n) } 
scope :by_proofs_size, -> { order(proofs_count: :desc) } 
+0

आप एक टन द्वारा प्रदर्शन बढ़ाने के लिए शामिल (: सबूत) को हटा सकते हैं। वर्तमान में, आप सभी डेटा लोड कर रहे हैं: सबूत, जब आपको वास्तव में आवश्यकता होती है तो त्वरित गणना क्वेरी होती है। कोशिश करके देखो। –

+0

@RobVolk यह कुछ पुराना कोड था! सर उठाने के लिए धन्यवाद! – Damien

+0

यह आपको एप्लिकेशन को मार देगा क्योंकि आपको डेटाबेस से सभी प्रमाणों के साथ सभी सप्ताह प्राप्त होंगे, आपके आवेदन की स्मृति – antiqe

0

अगर मैं रास्ता बंद कर रहा हूं तो मुझे माफ़ कर दो - लेकिन क्या आप सप्ताह की तालिका में एक साधारण counter_cache का उपयोग करने में सक्षम होंगे? फिर आप सप्ताह.proofs_count की तरह कुछ कर सकते हैं।

+0

हाँ, जैसा कि मैंने अपने प्रश्न में कहा था, मुझे पता है कि counter_cache एक विकल्प है, लेकिन अगर इस मामले में संभव हो तो मैं एक प्रश्न पूछूंगा। अगर वह काम नहीं करेगा, तो मैं निश्चित रूप से काउंटर कैश करूँगा। – eagspoo

4

मैं डॉन ' टी पता है कि यह सबसे अच्छा समाधान है, क्योंकि यह इसे सरणी के माध्यम से मानचित्र करता है, लेकिन यह काम करता है: (यहां उल्लिखित अन्य समाधान मुझे अपवाद देता है)

class Week < ActiveRecord::Base 

    scope :has_proofs, -> { any_in(:_id => includes(:proofs).select{ |w| w.proofs.size > 0 }.map{ |r| r.id }) } 

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

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