在Rails 3中,如果Order
有许多OrderRows
,
如果我调用sum函数,我会执行不需要的查询
Order.eager_load(:order_rows).find(xxx).order_rows.sum{|x| x.unit_taxed_cents}
OrderRow Load (0.6ms) SELECT "order_rows".* FROM "order_rows" WHERE "order_rows"."order_id" = XXXX
=> 17900
相反,如果我使用例如地图,则不执行附加查询:
Order.eager_load(:order_rows).find(xxx).order_rows.inject(0){|sum, r| sum + r.unit_taxed_cents }
=> 17900
根据定义(http://apidock.com/rails/v3.1.0/Enumerable/sum),2个函数应该是相同的东西
为什么它的表现不像预期?
由于
编辑:
更好地探索铁路的作用,
Order.eager_load(:order_rows).find(xxx).order_rows.method(:sum).source_location
返回
gems/activesupport-3.2.18/lib/active_support/core_ext/enumerable.rb
该功能的定义是:
def sum(identity = 0, &block)
if block_given?
map(&block).sum(identity)
else
inject(:+) || identity
end
end
因此,如果我运行
,我会期待同样无用的额外查询Order.eager_load(:order_rows).find(xxx).order_rows.map{|x| x.subtotal_taxed}.sum
相反它没有发生,行为是正确的