2008-09-17 7 views
5

मेरे पास कुछ मॉडल हैं जिन पर कस्टम खोज स्थितियां रखने की आवश्यकता है। उदाहरण के लिए, यदि मेरे पास एक संपर्क मॉडल है, तो हर बार Contact.find कहा जाता है, मैं उन संपर्कों को प्रतिबंधित करना चाहता हूं जो केवल उपयोग में खाते से संबंधित हैं।ActiveRecord में "ढूंढें" ओवरराइड करना DRY तरीका

मैं गूगल (जो मैं एक छोटे से कस्टमाइज़ कर दिया है) के माध्यम से इस पाया:

def self.find(*args) 
    with_scope(:find => { :conditions => "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do 
    super(*args) 
    end 
end 
:

def self.find(*args) 
    with_scope(:find => { :conditions => "account_id = #{$account.id}" }) do 
    super(*args) 
    end 
end 

यह महान काम करता है, कुछ अवसरों जहां ACCOUNT_ID अस्पष्ट है के लिए छोड़कर तो मैं यह करने के लिए अनुकूलित

यह भी बहुत अच्छा काम करता है, हालांकि, मैं इसे शुष्क बनाना चाहता हूं। अब मेरे पास कुछ अलग मॉडल हैं जो मैं इस तरह के फ़ंक्शन का उपयोग करना चाहता हूं। इसे करने का बेहतरीन तरीका क्या है?

जब आप उत्तर देते हैं, तो कृपया हमारे दिमाग को मेटाप्रोग्रामिंग रूबी-फु को समझने में मदद करने के लिए कोड शामिल करें।

(मैं रेल v2.1 उपयोग कर रहा हूँ)

उत्तर

8

आप हमें बता नहीं जो रेल प्रयोग कर रहे हैं के संस्करण [संपादित करें - यह पटरियों पर है 2.1 इस प्रकार निम्नलिखित सलाह पूरी तरह चालू है], लेकिन मैं करूंगा recommand आप अधिक भार के बजाय निम्न फ़ॉर्म का उपयोग मिल:

account.contacts.find(...) 

यह स्वचालित रूप से एक गुंजाइश जहां उपयोगकर्ता खंड शामिल किया गया है में खोजने लपेट पाएंगे (क्योंकि आप ACCOUNT_ID है मुझे लगता है कि आप खाते कहीं पास है)

मेरा सुझाव है कि आप निम्नलिखित जांचें स्कोप

+0

धन्यवाद जीन, कि एक का इलाज काम करते हैं और शायद सही तरीका है जाएगा इसे करने के लिए। खाता का परिचय मौजूदा कोड के लिए एक नया जोड़ा है, इसलिए मुझे लगता है कि मैं उस परिप्रेक्ष्य से आने से जटिल चीजों से अधिक था। मैं खाता द्वारा स्कॉप्ड होने के लिए मौजूदा कोड को जाकर संशोधित कर दूंगा। –

0

आपकी समस्या के लिए एक विशिष्ट जवाब देने के लिए, मैं एक में ऊपर उल्लेख किया विधि चलती सुझाव देंगे प्रश्न में मॉडल द्वारा मॉड्यूल शामिल किया जाना चाहिए; ताकि आप

class Contact 
    include NarrowFind 
    ... 
end 

पुनश्च होगा। खाता_आईडी से बचने के एसक्यूएल के लिए देखें, आपको शायद :conditions=>[".... =?", $account_id] सिंटैक्स का उपयोग करना चाहिए।

+0

यह मॉडल के आधार खोजक को पूरी तरह से ओवरराइड करने का सबसे बुरा विचार है क्योंकि यह प्लगइन लेखकों (सोचने वाली खोज प्लगइन) सहित टीम के बाहर किसी से भी उम्मीदों को तोड़ देगा, रेलों को तोड़ने के जोखिम का उल्लेख न करें (संभावना नहीं है लेकिन संभव नहीं है) – Jean

5

जीन की सलाह अच्छी है।अपने मॉडल मान लिया जाये कि इस तरह दिखेगा:

class Contact < ActiveRecord::Base 
    belongs_to :account 
end 

class Account < ActiveRecord::Base 
    has_many :contacts 
end 

आप चाहिए चालू खाते का contacts संघ का उपयोग कर यह सुनिश्चित करें कि आप केवल Contact रिकॉर्ड हो रही है उस खाते के दायरे वाला है, तो हो:

@account.contacts 

आप अपने संपर्कों क्वेरी के लिए आगे की स्थिति में जोड़ना चाहते हैं, तो आप उन्हें खोजने का उपयोग कर निर्दिष्ट कर सकते हैं:

@account.contacts.find(:conditions => { :activated => true }) 

और आप अपने आप को सह पाते हैं nstantly सक्रिय उपयोगकर्ताओं के लिए क्वेरी, आप एक नामित दायरे में refactor कर सकते हैं:

class Contact < ActiveRecord::Base 
    belongs_to :account 
    named_scope :activated, :conditions => { :activated => true } 
end 

जो तुम तो इस तरह का प्रयोग करेंगे:

@account.contacts.activated 
संबंधित मुद्दे