विशेषता मान द्वारा ऑब्जेक्ट्स के फ़िल्टरिंग रेल्स


96

इसलिए मैं db के लिए एक क्वेरी करता हूं और मेरे पास वस्तुओं का एक पूरा सरणी है:

@attachments = Job.find(1).attachments

अब जब मेरे पास एक ऑब्जेक्ट है, तो मैं एक और डीबी क्वेरी नहीं करना चाहता हूं, लेकिन मैं Attachmentऑब्जेक्ट के आधार पर सरणी को फ़िल्टर करना चाहूंगा file_typeताकि मेरे पास सूची हो सके attachmentsकि फ़ाइल का प्रकार कहां है 'logo'और फिर दूसरी सूची attachmentsकहां है फ़ाइल प्रकार है'image'

कुछ इस तरह:

@logos  = @attachments.where("file_type = ?", 'logo')
@images = @attachments.where("file_type = ?", 'image')

लेकिन db क्वेरी के बजाय मेमोरी में।


के लिए एक अच्छा उपयोग के मामले की तरह लगता है partition- उदाहरण के यहाँ
SRack

जवाबों:


172

प्रयत्न :

यह ठीक है :

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

लेकिन प्रदर्शन के लिहाज से आपको दो बार @attachments को पुनरावृत्त करने की आवश्यकता नहीं है:

@logos , @images = [], []
@attachments.each do |attachment|
  @logos << attachment if attachment.file_type == 'logo'
  @images << attachment if attachment.file_type == 'image'
end

2
जैसा कि @ विक का समाधान बहुत अधिक आदर्श है, मैं सिर्फ बाइनरी मामलों में जोड़ूंगा, आप चीजों को मीठा बनाने के लिए एक 'विभाजन' फ़ंक्शन का उपयोग कर सकते हैं। रूबी-doc.org/core-1.9.3/Enumerable.html#method-i-partition
व्लाद

धन्यवाद @Vlad, शांत, लेकिन यह तभी समर्थन करता है जब हमें ऑब्जेक्ट से केवल दो चीजें एकत्र करने की आवश्यकता होती है।
विक

1
हां, इसीलिए मैंने "बाइनरी" :) कहा। प्रश्न में, स्पष्ट रूप से लोगो या छवि का विकल्प था, इसलिए मैंने इसे पूर्णता के लिए जोड़ा।
व्लाद

8

अगर आपके अटैचमेंट हैं

@attachments = Job.find(1).attachments

यह अनुलग्नक ऑब्जेक्ट की सरणी होगी

File_type के आधार पर फ़िल्टर करने के लिए चयन विधि का उपयोग करें।

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' }
@images = @attachments.select { |attachment| attachment.file_type == 'image' }

यह किसी भी db क्वेरी को ट्रिगर नहीं करेगा।


2

क्या आपने उत्सुक लोडिंग की कोशिश की है?

@attachments = Job.includes(:attachments).find(1).attachments

क्षमा करें, मैं स्पष्ट नहीं हो रहा हूं: किसी विशेषता विशेषता के मान द्वारा सरणी के माध्यम से लूप किए बिना मैं कैसे फ़िल्टर करूं?
जोपोर

अगर मैं सही तरीके से समझ गया, तो आप कम db क्वेरी चाहते हैं, विशेष रूप से, एक बार जैसे कि @attachments = Job.first.attachmentsनिष्पादित की गई क्वेरी , आप @attachmentsइस बीच लूप करना चाहते हैं कि आप कोई और अधिक db क्वेरी नहीं चाहते हैं। यह आप क्या करना चाहते हैं?
सियावी शेन

मैं एक db क्वेरी करता हूं और ऑब्जेक्ट की एक सरणी प्राप्त करता हूं। मैं तब अपनी विशेषताओं के मूल्य के आधार पर वस्तुओं को फ़िल्टर करके उस एक सरणी से दो अलग-अलग सूचियाँ बनाना चाहता हूँ (मूल पोस्ट देखें) - चीयर्स
जोपोर


0

मैं इसके बारे में थोड़ा अलग तरीके से जाना चाहता हूँ। अपनी क्वेरी की संरचना केवल वही करें जो आपको चाहिए और वहां से अलग हो जाए।

तो अपनी क्वेरी को निम्न करें:

#                                vv or Job.find(1) vv
attachments = Attachment.where(job_id: @job.id, file_type: ["logo", "image"])
# or 
Job.includes(:attachments).where(id: your_job_id, attachments: { file_type: ["logo", "image"] })

और फिर डेटा का विभाजन करें:

@logos, @images = attachments.partition { |attachment| attachment.file_type == "logo" }

कि आप एक साफ और कुशल तरीके से बाद में डेटा मिलेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.