2015-01-06 6 views
28

मैं चयन करने के लिए कोशिश कर रहा था एक विशेषता के आधार पर uniq वस्तुओं का उपयोग करते हुए @videos.uniq{|p| p.author}रेल: सरणी के लिए activerecord संबंध मोड़ने का सही तरीका?

time = Time.new(2014, 12) 
    start_time = time.beginning_of_month 
    end_time = time.end_of_month 

    videos = Video.where("created_at > ? AND created_at < ?", start_time, end_time).where("likes > ?", 15) 
    selected_videos = videos.uniq{|p| p.author} 
    puts videos.count, videos.class, selected_videos.count 
#=> 23, Video::ActiveRecord_Relation, 23 

    videos_first = videos.first(23) 
    selected_videos = videos_first.uniq{|p| p.author} 
    puts videos_first.count, videos_first.class, selected_videos.count 
    #=> 23, array, 10 

.uniqActiveRecord_Relation के लिए नहीं है। और समस्या यह है कि क्वेरी Video::ActiveRecord_Relation लौटाती है, लेकिन मुझे array की आवश्यकता है।

निश्चित रूप से, यह to_a का उपयोग कर हासिल किया जा सकता है, लेकिन यह सुरुचिपूर्ण है?

  1. इसे संभालने का सही तरीका क्या है?
  2. activerecord:relation के लिए उपयोग करना संभव है?
+3

'to_a' * किसी भी * को सरणी में बदलने का सही तरीका है। – meagar

+2

एन + 1 क्वेरी के बारे में सावधान रहें। 'Video.where (...) का उपयोग करके आपके पास एक और अधिक कुशल क्वेरी होगी। {to_a.uniq {| p | को कॉल करने से पहले '(लेखक)' शामिल है। p.author} ' –

उत्तर

29

यदि आपको क्वेरी परिणाम तक पहुंचने की आवश्यकता है, तो ActiveRecord :: Relation instance पर केवल #to_a का उपयोग करें।

rails guides पर आप रेल 4.0 में उल्लेखनीय परिवर्तनों को पा सकते हैं: "मॉडल.अॉल अब रिकॉर्ड्स की सरणी के बजाय एक ActiveRecord :: रिलेशनशिप देता है। यदि आप वास्तव में एक सरणी चाहते हैं तो संबंध # to_a का उपयोग करें। कुछ विशिष्ट मामलों में , यह अपग्रेड करते समय टूटने का कारण बन सकता है। " यह अन्य संबंध विधियों के लिए मान्य है जैसे: कहां।

selected_videos = videos.to_a.uniq{|p| p.author} 
2

.uniq जब यह पूर्ण सक्रिय रिकॉर्ड रिकॉर्ड भर में लागू किया जाता है ज्यादा मतलब नहीं है।

यह देखते हुए कि कम से कम एक या एक से अधिक तीनों विशेषताओं में से - id, created_at, और updated_at - हर पंक्ति के लिए अलग हैं, videos.uniq{|p| p.author} लागू करने के जहां videos सभी क्षेत्रों सहित एक ActiveRecord::Relation है, ActiveRecord::Relation में सभी पंक्तियों को वापस आ जाएगी।

जब ActiveRecord::Relation ऑब्जेक्ट में मानों का सबसेट होता है, uniq उनके द्वारा अलग-अलग मानों को समझने में सक्षम होंगे।

उदाहरण: videos.select(:author).uniq.count आपके उदाहरण में 10 देगा।

ActiveRecord::Relation#uniq और Array#uniq के बीच का अंतर यह है कि ऐरे संस्करण एक ब्लॉक स्वीकार करता है और तुलना के लिए ब्लॉक के वापसी मूल्य का उपयोग करता है। ActiveRecord :: Uniq का रिलेशनशिप संस्करण बस ब्लॉक को अनदेखा करता है।

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