ActiveRecord:正在加载所有子关联的记录,但 select 任何子关联都满足条件

ActiveRecord: Loading records with all child association eager loaded, but select the ones that any of the children hits the condition

我有如下模型。

class Project < ActiveRecord::Base
  # id         :integer  
  # name       :string

  has_many :assignments
end

class Assignment < ActiveRecord::Base
  # id         :integer  
  # finished   :boolean
  # project_id :integer  

  belongs_to :project
end

我想加载有任何未完成作业的项目,但所有作业都已预先加载。希望在单个 SQL 查询中。

假设我有如下记录

- project_1
  - assignment [finished: false]
  - assignment [finished: false]
  - assignment [finished: false]

- project_2
  - assignment [finished: true]
  - assignment [finished: true]
  - assignment [finished: true]

- project_3
  - assignment [finished: true]
  - assignment [finished: false]
  - assignment [finished: true]

那么我要的记录是这样的

- project_1
  - assignment [finished: false]
  - assignment [finished: false]
  - assignment [finished: false]

- project_3
  - assignment [finished: true]
  - assignment [finished: false]
  - assignment [finished: true]

这是问题

  1. 我可以仅使用 ActiveRecord 的查询 arelsqueel gem 的表达式来实现吗?

  2. 如果没有,什么样的 SQL 查询适用于此?

我尝试了以下 ruby 代码,但它过滤掉了已完成的作业。

Project.eager_load(:assignments).where('assignments.finished = ?', false)

# which results in
# 
#- project_1
#  - assignment [finished: false]
#  - assignment [finished: false]
#  - assignment [finished: false]
#
#- project_3
#  - assignment [finished: false]

嘿,你可以使用 ActiveRecord 的查询来实现这个

@unfinished = Assignment.where(:finished => false).pluck(:project_id)

@projects = Project.includes(:assignments).where(:id => @unfinished)

Active Record with sql 在单个查询中为,

 Project.includes(:assignments).where("projects.id in (select project_id from assignments where assignments.finished = ?)", false)