具有匹配条件的子项的不同记录的ActiveRecord SUM

时间:2014-11-21 21:59:09

标签: ruby-on-rails rails-activerecord

我试图获得至少有days_to_completetraining_stages的{​​{1}}所有training_tasks的总和。 (请注意,我在名为is_complete: => false的引擎中工作

Training

示例数据

create_table :training_stages do |t|
  t.references :checklist, index: true
  t.string :name
  t.integer :days_to_complete

  t.timestamps
end

create_table :training_tasks do |t|
  t.references :stage, index: true
  t.string :description
  t.boolean :is_public, default: false, null: false
  t.boolean :is_complete, default: false, null: false

  t.timestamps
end

当我运行以下内容时,我得到48。

training_stages:
    id  checklist_id    name    days_to_complete    created_at  updated_at
    1   1   Intake Stage    8   2014-11-21 21:03:53 2014-11-21 21:03:53
    2   1   Document State  6   2014-11-21 21:03:53 2014-11-21 21:03:53

training_tasks:
    id  stage_id    description is_public   is_complete created_at  updated_at
    1   1   Task1   1   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    2   1   Task2   0   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    3   1   Task3   1   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    4   2   Task4   1   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    5   2   Task5   0   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    6   2   Task6   1   0   2014-11-21 21:03:53 2014-11-21 21:03:53
    7   2   Task7   0   0   2014-11-21 21:03:53 2014-11-21 21:03:53

看起来这会为每个匹配条件的任务返回一个阶段,然后将它们全部汇总。所以我尝试了分组:

# Assume that stages already contains Stage.all
stages.includes(:tasks)
  .where(training_tasks: {is_complete: false})
  .sum(:days_to_complete)

这实际上会返回stages.includes(:tasks) .where(training_tasks: {is_complete: false}) .group("training_stages.id") .sum(:days_to_complete)

如何将总和限制在不同的阶段?

1 个答案:

答案 0 :(得分:0)

在RoR中你可以做到

stages.includes(:tasks)
 .where(training_tasks: {is_complete:false})
 .distinct.pluck(:days_to_complete).sum

stages.includes(:tasks)
 .where(training_tasks: {is_complete:false})
 .distinct.to_a.sum(&:days_to_complete)