我有一个模特频道。相关表有几列,例如点击。
因此Channel.all.sum(:clicks)
为我提供了所有频道的点击总和。
在我的模型中,我添加了一个新方法
def test
123 #this is just an example
end
现在,Channel.first.test
返回123
我想要做的是像Channel.all.sum(:test)
那样总结所有频道的测试值。
我得到的错误是测试不是一个列,当然不是,但我希望能够构建这个总和。
我怎么能实现这个目标?
答案 0 :(得分:2)
你可以尝试:
Channel.all.map(&:test).sum
如果点击是模型表的一列,请使用:
Channel.sum(:clicks)
答案 1 :(得分:1)
要解决您的问题,您可以
Channel.all.sum(&:test)
但尝试在数据库层实现它会更好,因为使用Ruby进行处理可能会增加内存和效率。
如果你想通过一个带参数的方法求和:
Channel.all.sum { |channel| channel.test(start_date, end_date) }
答案 2 :(得分:1)
你在这里谈论的是两件截然不同的事情:
ActiveRecord::Calculations.sum
对数据库中列的值进行求和:
SELECT SUM("table_name"."column_name") FROM "column_name"
如果您拨打Channel.sum(:column_name)
,就会发生这种情况。
.sum
方法ActiveSupport also extends the Enumerable module:
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 }
使用后者会导致严重的性能问题,因为它会将所有数据从数据库中提取出来。
答案 3 :(得分:0)
或者你这样做。
Channel.all.inject(0) {|sum,x| sum + x.test }
您可以将0更改为您希望总和开始的任何值。