2012-06-05 5 views
5

मैं रूबी 3.2.2 पर रूबी का उपयोग कर रहा हूं और मैं उन संबंधित वस्तुओं पर एक विशेषता मान "निर्दिष्ट"/"फ़िल्टरिंग" द्वारा संबंधित ऑब्जेक्ट्स को पुनर्प्राप्त/स्कोप करना चाहता हूं। यही कारण है, इस समय मैं निम्नलिखित कोड का उपयोग कर रहा:दो अलग-अलग वर्गों में उपयोग की जाने वाली स्कोप विधियों को कैसे ड्रॉ करें?

class Article < ActiveRecord::Base 
    def self.search_by_title(search) 
    where('articles.title LIKE ?', "%#{search}%") 
    end 
end 

class ArticleAssociation < ActiveRecord::Base 
    def self.search_by_article_title(search) 
    joins(:article).where('articles.title LIKE ?', "%#{search}%") 
    end 
end 

उपरोक्त कोड में where('articles.title LIKE ?', "%#{search}%") खंड दो बार दोहराया है और इसलिए मैंने सोचा कि यह सूखी सिद्धांत के साथ सुधार किया जा सकता है: यह संभव है उपयोग करने के लिएArticle.search_by_titleविधि सीधेArticleAssociation.search_by_article_titleविधि में विधि?


विशिष्ट उपयोग के मामलों रहे हैं:

  • ArticleAssociation.search_by_article_title("Sample string")
  • Article.search_by_title("Sample string")
+0

मुझे एक परियोजना (4 संबंधित मॉडल) में इसी स्थिति का सामना करना पड़ा और मैंने सामान्य खोज विधियों को रखने के लिए एक मॉड्यूल बनाया। यूट बिल्कुल ठीक नहीं है जो आप पूछते हैं लेकिन यह एक सामान्य समाधान है। – tokland

+0

कक्षाओं के बीच साझा कोड आमतौर पर मॉड्यूल – apneadiving

+0

में मॉड्यूल में समाप्त होता है, स्क्वायर के सिफ्टर्स का उपयोग इस पर किया जा सकता है, लेकिन एआर के बजाय स्क्वायर का उपयोग करना एक बड़ा बदलाव है .. https://github.com/ernie/squeel#sifters – tokland

उत्तर

2

जब तक आप पूरी तरह से कोड संरचना बदलने, नहीं।

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

हालांकि, मुझे पता है कि यह कष्टप्रद है जब लोगों को इसलिए यहाँ अपने प्रश्न का उत्तर नहीं है,:

class Article < ActiveRecord::Base 
    SEARCH_BY_TITLE=lambda {|obj, search| obj.where('articles.title LIKE ?', "%#{search}%")} 
    def self.search_by_title(search) 
    SEARCH_BY_TITLE.call(self, search) 
    end 
end 

class ArticleAssociation < ActiveRecord::Base 
    def self.search_by_article_title(search) 
    Article::SEARCH_BY_TITLE.call(joins(:article),search) 
    end 
end 

कि सिर्फ एक निरंतर कि एक निर्दिष्ट वस्तु पर where कॉल करता है के रूप में एक लैम्ब्डा बनाता है। दोनों विधियां सिर्फ उस लैम्ब्डा को लपेटें।

नोट: हालांकि इसे अधिक सुरुचिपूर्ण माना जा सकता है, लेकिन यह प्रदर्शन को बहुत कम कर देगा, क्योंकि लैम्ब्डा, बंद, और अतिरिक्त कॉल रूबी जैसे गतिशील भाषा में महंगे हैं। लेकिन मुझे नहीं लगता कि यह आपके लिए एक मुद्दा है।

class Property < ActiveRecord::Base 
    include Listable 
end 

:

module Listable 
    extend ActiveSupport::Concern 

    module ClassMethods 
    # Search a listable module search in properties (or related) tables 
    def search_from_properties(string) 
     return where({}) if string.blank? 
     associations = self.reflect_on_all_associations.map(&:name) & 
     [:property, :properties, :supplier, :suppliers, :address] 
     s = "%#{string}%" 
     associations.inject(self, :includes).where(
     ((Address[:base] =~ s) | (Address[:city] =~ s)) | 
     ((Property[:owner] =~ s) | (Property[:cif] =~ s)) | 
     ((Supplier[:cups] =~ s) | (Supplier[:contract] =~ s)) 
    ) 
    end 
    end 
end 

अब बस संबंधित कक्षाओं में इस मॉड्यूल में शामिल हैं:

+0

@ Linux_iOS.rb.cpp.c.lisp.n जोड़ें - अपने उत्तर के लिए धन्यवाद। हालांकि, मेरे पास * बहुत सारे स्थान हैं जहां मुझे कोड * 'कहां ('articles.title LIKE?',"% # {Search}% ") का उपयोग करने की आवश्यकता है, और यहां तक ​​कि यदि आपने कहा" छोटे एक विधि के लिए -क्या चीजें जैसे कि यह एक अपशिष्ट है और शायद आपके कोड को और अधिक गूढ़ बना देगा ", * क्या मेरे वर्गों में हर जगह उस कोड को दोहराना बुरा है? * – Backo

+1

@ बैको: यदि आप कोड का बहुत उपयोग करते हैं, तो लैम्ब्डा शायद बेहतर है विचार। यदि आप इसे केवल दो बार उपयोग करते हैं, उदाहरण के तौर पर, आप बेहतर दोहरा रहे हैं। – Linuxios

1

ओपी अनुरोध के अनुसार, मैं कोड है कि मैं एक 3-मॉड्यूल खोज के लिए लिखा था एक मॉड्यूल का उपयोग करके पोस्ट नोट: सभी मॉडलों में संगठनों को अन्य लोगों तक पहुंचने के लिए परिभाषित किया गया है (यही कारण है कि joins कार्य)। इसके अलावा, यह this wrapper over AR का उपयोग करता है।

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