我想通过其关系值过滤具有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