[英]Rails, sum the aggregate of an attribute of all instances of a model
我有一个模特频道。 相关表有几列,例如单击。
所以Channel.all.sum(:clicks)
给我所有频道的点击总和。
在我的模型中,我添加了一种新方法
def test
123 #this is just an example
end
所以现在Channel.first.test
返回123
我要执行的操作类似于Channel.all.sum(:test)
,该操作将所有通道的测试值相加。
我得到的错误是测试不是一列,当然不是,但我希望直到能够建立这个总和。
我怎样才能做到这一点?
您可以尝试:
Channel.all.map(&:test).sum
如果点击是模型表的一列,请使用:
Channel.sum(:clicks)
为了解决您的问题,您可以
Channel.all.sum(&:test)
但是最好尝试在数据库层上实现它,因为使用Ruby进行处理可能会增加内存和效率。
如果要通过带有参数的方法求和:
Channel.all.sum { |channel| channel.test(start_date, end_date) }
您在这里谈论的是两件截然不同的事情:
ActiveRecord::Calculations.sum
对数据库中列的值求和:
SELECT SUM("table_name"."column_name") FROM "column_name"
如果调用Channel.sum(:column_name)
,就会发生这种情况。
ActiveSupport还使用.sum
方法扩展了Enumerable模块 :
module Enumerable
def sum(identity = nil, &block)
if block_given?
map(&block).sum(identity)
else
sum = identity ? inject(identity, :+) : inject(:+)
sum || identity || 0
end
end
end
这会循环遍历内存中的所有值,并将它们加在一起。
Channel.all.sum(&:test)
等效于:
Channel.all.inject(0) { |sum, c| sum + c.test }
使用后者可能会导致严重的性能问题,因为它将所有数据从数据库中拉出。
或者,您也可以这样做。
Channel.all.inject(0) {|sum,x| sum + x.test }
您可以将0更改为希望总和开始的任何值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.