ActiveRecord #includes, with condition, but load all relations, 而不仅仅是那些匹配条件

ActiveRecord #includes, with condition, but load all relations, not just those matching condition

我有 ActiveRecord 模型 Parent 和 Kid。 Parent他们有很多孩子。

我有一个 Parent,他的名字叫爸爸,有 3 个孩子,他们的名字分别是 Abel、Bobby 和 Cain。我想根据其中 1 个孩子的名字找到 Parent。

parent = Parent.includes(:kids).
  find_by(kids: { name: 'Bobby' })

以上查询提供了我想要的 Parent,但 parent.kids 只包括 Bobby。我希望 Abel 和 Cain 也包含在 parent.kids 中,就像我这样做一样:

Parent.find_by(name: 'Dad').kids

我能做到:

Parent.includes(:kids).
  find_by(kids: { name: 'Bobby' }).
  tap { |parent| parent&.kids.reload }

但是没有一个“更好”的方法来接剩下的孩子吗?例如,有没有一种方法可以在查询 parent 时加载 parent 的所有孩子(通过一个 SQL 语句)?

如何使 Parent.includes(:kids).find_by(kids: { name: 'Bobby' } 成为子查询

Parent.includes(:kids).where(id: Parent.includes(:kids).find_by(kids: { name: 'Bobby' })

你想要一个 INNER JOIN:

parents = Parent.joins(:kids).where(kids: { name: 'Bobby' })

这将仅包含来自 parents 且孩子们 table 匹配的行。您可以将其应用为子查询以避免删除其余的连接行:

parents = Parent.where(
            id: Parent.joins(:kids).where(kids: { name: 'Bobby' })
          ).includes(:kids)