rails 3.2
Invoice.sum(:amount)
准确返回金额列中所有值的总和。
如果我执行以下操作:
invoices = Invoice.all
然后:
invoices.sum(:amount)
我收到以下错误:
NoMethodError: undefined method `+'
有办法做到这一点吗?
答案 0 :(得分:3)
如果您确定没有单amount == nil
那么您尝试过的话应该有效。如果你有一个零列,这将导致
NoMethodError: undefined method '+' for nil
。在这种情况下,您可以invoices.map(&:amount).compact.sum
或invoices.sum { |i| i.amount || 0 }
答案 1 :(得分:2)
这是因为#sum是一个ActiveRecord方法。它本质上正在做的是将聚合构建到数据库查询中,如此(在SQL中):
SELECT SUM(name_of_column_to_sum) FROM table_name;
如果要返回值并将它们存储在变量(#all)中,
SELECT * FROM table_name;
然后总结它们,您不再使用ActiveRecord查询,而是使用ActiveRecord关系(从ActiveRecord查询返回的类似数组的对象)。所以,那时你需要使用vanilla Ruby来总结。你可以使用#map然后使用#sum,但是使用#inject会更快更干净,就像这样:
invoices.inject(0){ |sum, invoice| sum + invoice.amount }
答案 2 :(得分:0)
您必须使用map
功能,如下所示:
invoices.map(&:amount).sum