繁体   English   中英

Rails,将模型所有实例的属性的总和求和

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM