如何在Ruby on Rails中汇总连接表中的所有相关记录?

时间:2014-06-30 17:06:01

标签: ruby-on-rails ruby activerecord

我的Ruby on Rails应用程序中有以下模型:

class Invoice < ActiveRecord::Base

  has_many :allocations
  has_many :payments, :through   => :allocations

end

class Allocation < ActiveRecord::Base

  belongs_to :invoice
  belongs_to :payment

end

class Payment < ActiveRecord::Base

  has_many :allocations, :dependent => :destroy
  has_many :invoices,    :through => :allocations

end

我的问题是,在Allocation课程中,我想使用所有关联发票的total_amount,最好是before_save回调。

现在不可能,因为在保存allocation对象时,它只与一个特定invoice对象相关联。 / p>

如何通过最少的数据库查询来完成这项工作?

1 个答案:

答案 0 :(得分:3)

Invoice.where(asdfasdfasdf).map(&:allocations).flatten.map(&:total_amount).compact.inject(:+)

因为这是rails,所以数据库调用不算什么。总结一组数字,你可以使用它:

ary = [0,12,2,6,nil]
ary.compact.inject(:+)
#=> 20

你可以稍微清理一下:

class Invoice
#...
  def total_amount
    allocations.map(&:total_amount).inject(:+) #throws error if there is 1 nil 'total_amount data' value
  end 

  def self.sum_allocation_amounts(sql)
    where(sql).map(&:total_amount).inject(:+)
  end

end

无法在没有错误的情况下调用Invoice类方法中的self.map(&:allocations),因此我将传递一些基本的sql作为变通方法。理想情况下,我可以直接在activerecord的菊花链上调用此方法,其中调用Invoice但是现在没有为我工作(&#34;未定义的方法映射&#39;用于Class& #34)

Invoice.sum_allocation_amounts("democol = 'demo params'")