我的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>
如何通过最少的数据库查询来完成这项工作?
答案 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'")