按关系过滤活动记录,但不按关系本身过滤



我想通过其关系值过滤具有has_many关系的模型。

这可以通过使用Foo.include(:bars).where(bars: { foobar: 2 })轻松实现。

如果我们的数据库中有这样的对象:

{
  id: 1,
  bars: [
    { id: 4, foobar: 1 },
    { id: 5, foobar: 2 }
  ]
}

此查询将仅返回以下内容:

{
  id: 1,
  bars: [
    { id: 5, foobar: 2 }
  ]
}

我仍想按此关系过滤我的记录,但接收该关系中的所有记录。

我能够通过使用类似的东西来实现这一点:Foo.include(:bars).joins('LEFT JOIN bars AS filtered_bars ON filtered_bars.foo_id = foos.id').where(filtered_bars: { foobar: 2 })但这看起来不是很漂亮。

有没有更好的方法可以做到这一点?

这就是includes的魔力 - 由于您在何处使用bar,因此它决定使用左连接并且不会预加载任何其他内容。您必须在此处明确加入并预注册关联:

Foo.joins(:bars).where(bars: {foobar: 2}).uniq.preload(:bars)

前段时间我做了一个关于那些神奇方法的演讲,你可以在这里找到它:https://skillsmatter.com/skillscasts/6731-activerecord-vs-n-1

相关内容

  • 没有找到相关文章

最新更新