发生这种情况的原因是因为平均方法是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