是否可以在模型的ActiveRecord虚拟属性上使用聚合函数?

时间:2015-03-11 18:41:32

标签: ruby-on-rails ruby-on-rails-4

我有两个类似于这些的模型(请不要介意上下文,我只是想说明一个例子,并且首先想到的是客户购买关系):

# client.rb
# name:string

class Client < ActiveRecord::Base
   has_many :purchases, dependent: :destroy

   def profit
     self.purchases.sum('price - cost')
   end
end

# purchase.rb
# client_id:integer, product_id:integer, cost:decimal, price:decimal

class Purchase < ActiveRecord::Base
  belongs_to :client
  belongs_to :product
end

这适用于单个记录,如下所示:

> a=Client.first # OK
> a.profit       # 40.23

但是,如果我想对“利润”(它本身就是一个SUM)的值进行求和,我会得到一个错误,这是完全可以理解的。

> a.sum(:profit)   # no such column: profit

有没有办法在没有在整个表中运行循环的情况下从中获取SUM?目前我这样做:

sum=0
Client.each do |a|
   sum+=a.profit
end

这是有效的,但是我想知道是否有更简单的方法通过ActiveRecord,或者甚至在SQL中这样做?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您无法直接使用您的:利润方法,但您可以获取每个客户的计算值,而无需迭代每个客户。同时使用groupsum

Purchase.group(:client_id).sum('price - cost')

这将返回一个哈希,其中密钥为client_id,值为该客户的所有购买price - cost的总和。