rails升级包括方法行为改变

2nbm6dog  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(263)

我已经挖了几天,还没有找到一个很好的解释这种行为的变化。我正在将rails应用程序从3.2升级到5.2,这是我的Rails3应用程序通过测试的代码。

ps = Project.includes(:rentals).where('rentals.id IN (?)', [1,2,3,4])

这就产生了一个大的老左连接sql查询。
但是如果我在Rails5中执行相同的查询,我会得到一个mysql错误

ActiveRecord::StatementInvalid (Mysql2::Error: Unknown column 'rentals.id' in 'where clause': SELECT  `projects`.* FROM `projects` WHERE (rentals.id IN (1,2,3,4)) LIMIT 11 /*application:ConHQ*/)

我对includes的理解是,它应该执行单独的查询,除非includes表在where子句中被引用,在这种情况下,它应该执行左联接。但这似乎不是在这里发生的。在这种情况下,使用U-load工作:

ps = Project.eager_load(:rentals).where('rentals.id IN (?)', [1,2,3,4])

但我认为这也应该如此。
我还注意到,有时include执行的查询与eager\u load相同

@project = Project.find(174)
@project.rentals.eager_load(:equipment_name).where('equipment_names.id IN (?)', [1,2,3,4])
@project.rentals.includes(:equipment_name).where('equipment_names.id IN (?)', [1,2,3,4])

在这种情况下,加载和包含都执行左连接。我还没有找到任何文档来解释为什么在这些情况下包含不同的行为。includes究竟如何选择它执行的查询?

bnl4lu3b

bnl4lu3b1#

includes 只需告诉activerecord数据应该立即加载,但它可以随心所欲地实现这一点。如果要在查询中引用另一个模型,则必须使用 references(:rentals) ,也是。
activerecordapi是非常强大和通用的,但是ruby和它的库通常都是这样,有很多方法可以实现某些功能。在这种情况下,还可以使用 merge 合并在另一种关系中。

rentals = Rental.where(id: [1,2,3,4])
projects = Project.joins(:rentals).merge(rentals) # you can additionally add includes, too, if you want to access the rentals

这样做还有一个额外的优点,即您不需要关心 Rental 模型。

相关问题