發生這種情況的原因是因爲平均方法是ActiveRecord::Relation
,而不是Arel,這會強制計算。
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
的內部,你可以得到你如何在它使用SQL得到。
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"
超!感謝您分享您用來解決這個問題的方法..將在未來派上用場! – Zabba 2011-03-03 17:09:59
這就是我喜歡Ruby的原因。您可以隨時詢問REPL和來源。這是源於不止一種意義的詞語! – 2011-03-03 18:02:57
這在許多不同的邏輯中幫助我很多。偉大的工作人。 – 2012-11-09 05:11:57