2011-03-02 13 views
13

मैं AREL से SQL पाने के लिए कोशिश कर रहा हूँ, लेकिन यह इस मामले में काम नहीं करता मैं average(:stars) का उपयोग करें:`औसत()` का उपयोग करते समय AREL में `to_sql` का उपयोग कैसे करें?

यह काम करता है:

Review.where("reviewed_user_id = ?", self.reviewed_user_id).to_sql 
#=> "SELECT `reviews`.* FROM `reviews` WHERE (reviewed_user_id = 3)" 

यह NoMethodError कारण बनता है:

Review.where("reviewed_user_id = ?", self.reviewed_user_id).average(:stars).to_sql 
#=> undefined method `to_sql' for 3:Fixnum 

ताकि इसका मतलब है कि to_sql AREL ऑब्जेक्ट के बजाय AREL के परिणाम पर कॉल किया जा रहा है - लेकिन क्यों?

जेनरेट किए गए एसक्यूएल कैसे प्राप्त करें?

उत्तर

24

ऐसा होने का कारण यह है कि औसत विधि ActiveRecord::Relation पर है, न कि एरल, जो गणना को मजबूर करती है।

m = Review.where('id = ?', 42).method(:average) 
#=> #<Method: ActiveRecord::Relation(ActiveRecord::Calculations)#average> 
m.source_location # or m.__file__ if you're on a different version of Ruby 
#=> ["/Users/jtran/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.0.4/lib/active_record/relation/calculations.rb", 65] 

ActiveRecord::Calculations के आंतरिक भागों बाहर की जाँच करके, आप कैसे एसक्यूएल यह का उपयोग करता है पर प्राप्त करने के लिए प्राप्त कर सकते हैं।

my_reviewed_user_id = 42 
relation = Review.where('reviewed_user_id = ?', my_reviewed_user_id) 
column = Arel::Attribute.new(Review.unscoped.table, :stars) 
relation.select_values = [column.average] 
relation.to_sql 
#=> "SELECT AVG(\"reviews\".\"stars\") AS avg_id FROM \"reviews\" WHERE (reviewed_user_id = 42)" 

यदि आप कंसोल पर काम कर रहे हैं तो सावधान रहें। ActiveRecord::Relation कैश चीजें इसलिए यदि आप ऊपर से कंसोल लाइन में टाइप करते हैं, तो यह वास्तव में काम नहीं करेगा, क्योंकि सुंदर प्रिंटिंग संबंधों को मजबूर करती है। अर्धविराम से उपरोक्त को अलग करना और कोई नई लाइन, हालांकि, काम करेगी।

वैकल्पिक रूप से, तुम इतनी तरह सीधे अरेल उपयोग कर सकते हैं,:

my_reviewed_user_id = 42 
reviews = Arel::Table.new(:reviews) 
reviews.where(reviews[:reviewed_user_id].eq(my_reviewed_user_id)).project(reviews[:stars].average).to_sql 
#=> "SELECT AVG(\"reviews\".\"stars\") AS avg_id FROM \"reviews\" WHERE \"users\".\"reviewed_user_id\" = 42" 
+0

सुपर! इस विधि को साझा करने के लिए उपयोग की जाने वाली विधि को साझा करने के लिए धन्यवाद .. भविष्य में काम में आ जाएगा! – Zabba

+0

यही कारण है कि मुझे रुबी पसंद है। आप हमेशा आरईपीएल और स्रोत से पूछ सकते हैं। यह शब्द के एक से अधिक अर्थों में स्रोत है! –

+0

यह मुझे कई अलग-अलग तर्कों में बहुत मदद करता है। महान काम आदमी –

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