【问题标题】:ActiveRecord #includes, with condition, but load all relations, not just those matching conditionActiveRecord #includes,有条件,但加载所有关系,而不仅仅是那些匹配条件
【发布时间】:2020-05-29 19:35:36
【问题描述】:

我有 ActiveRecord 模型 Parent 和 Kid。父母有很多孩子。

我有一个叫爸爸的父母,有 3 个孩子,他们的名字是 Abel、Bobby 和 Cain。我只想根据其中 1 个孩子的名字找到家长。

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 }

但是,难道没有一种“更好”的方式来接其他孩子吗?例如,有没有一种方法可以在查询父级时加载父级的所有子级(通过一个 SQL 语句)?

【问题讨论】:

    标签: ruby-on-rails ruby join activerecord relation


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      你想要一个INNER JOIN

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

      这将只包括来自父母的行与孩子表中的匹配。您可以将其作为子查询应用,以避免删除其余的连接行:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-04
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        相关资源
        最近更新 更多