使用范围从两个表计算SUM

时间:2014-06-18 14:27:13

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

我有两个包含以下字段的数据库表:

log_lines: id, user_id, date
fragments: id, log_line_id, amount

对应模型:

模型/ log_lines.rb

class LogLine < ActiveRecord::Base
  has_many :fragments, dependent: :destroy

  def total_amount
    fragments.sum(:amount)
  end
end

模型/ fragments.rb

class Fragment < ActiveRecord::Base
  belongs_to :log_line
end

我想根据user_id获得金额。执行该任务的SQL查询:

  

SELECT SUM(f.amount)FROM log_lines AS ll LEFT JOIN片段AS f ON   f.log_line_id = ll.id WHERE ll.user_id = 74123;

我在total_amount模型中创建了LogLine方法并从LogLine调用它 控制器:

amount = 0
ll_list = LogLine.where(:user_id => user_id)
ll_list.each { |ll| amount += ll.total_amount }

实际上它有效,但我认为它不是实现它的有效方法。因为在此类数据收集期间会执行许多数据库查询。

是否可以通过一个scope实现此目的?

1 个答案:

答案 0 :(得分:1)

这绝对可以通过一个scope实现。你可以使用:

class Logline < ActiveRecord::Base
  scope :user_amount, ->(user_id) { 
    select('sum(fragments.amount')
    .joins('LEFT JOIN fragments ON fragments.log_line_id = log_line.id')
    .where('log_line.user_id = ?', user_id)
  }
end

另一种方法:

class Logline < ActiveRecord::Base
  scope :user_amount, ->(user_id) {
    joins('LEFT JOIN fragments ON fragments.log_line_id = log_line.id')
    .where(fragments: { user_id: user_id })
    .sum('fragments.amount')
  }
end