我有一张有很多预订的餐馆的table。现在我想查询所有的餐厅,如果他们有保留2人,它应该预载这些协会。如果没有2人的预订,它仍然应该返回餐厅,但有一个空的关联。
为此,我尝试了以下查询:
Restaurant.eager_load(:reservations).where("number_of_people = ?", 2)
然而,这并不起作用,因为它会丢弃所有有预订的餐厅,但没有一家是两个人的。
所以我想做的是把这个条件变成连接条件。例如:
Restaurant.joins('LEFT OUTER JOIN \"reservations\" ON \"reservations\".\"restaurant_id\" = \"restaurants\".\"id\" AND \"reservations\".\"number_of_people\" = ?', 2)
这将给予我需要的结果,但是这不是预加载“保留”关联,而是导致N+1问题。
eager_load似乎不接受自定义查询。我发现了这些线索:https://github.com/rails/rails/issues/12270和JOIN ON ... AND conditions when eager loading association in ActiveRecord,但没有提供解决方案。
3条答案
按热度按时间omvjsjqw1#
我觉得迪帕克是对的。试试这个:
然后:
或
2ic8powd2#
试试
Restaurant.joins(:reservations).includes(:reservations).where("reservations.number_of_people = ?", 2)
pxyaymoc3#
我一直在努力寻找,从Rails 7.0开始,似乎不可能用动态条件来连接它。它可以与静态条件一起工作,或者你可以加入它并使用
where
过滤它(正如其他答案所建议的那样),但是当这两种解决方案都不适合时,有一些用例,我不认为有一个解决方案可以使它与ActiveRecord急切加载一起工作。你只能跳过使用ActiveRecord即时加载功能,直接创建一个单独的原始SQL请求并获取数据,比如:这只是一个最小的例子,我只设置了
id
的保留,因为我不知道你还有什么其他列,但这种方法允许你添加其他字段到Reservation
示例。这种方法也有它的警告,例如像这样创建的AR示例将具有persisted?
等于false
,除非您显式地重新加载它们(这将产生另一个SQL查询)。但只要你不关心persisted?
值,你就应该没事。