ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column for `where` query when using includes

ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column for `where` query when using includes

我有以下联想:

mobile_application.rb

has_many :events

event.rb

belongs_to :mobile_application

以下运行正常:

MobileApplication.includes(:events)
#=> MobileApplication Load (1.6ms)  SELECT `mobile_applications`.* FROM `mobile_applications`  ORDER BY created_at desc
#   Event Load (1.3ms)  SELECT `events`.* FROM `events` WHERE `events`.`mobile_application_id` IN (746, 745, 744, ....

但是当我尝试以下操作时,

MobileApplication.includes(:events).where("events.expiry_date >= ?", Time.zone.now)

它抛出一个错误:

MobileApplication Load (1.2ms)  SELECT `mobile_applications`.* FROM `mobile_applications` WHERE (events.expiry_date >= '2019-02-18 07:34:40.738517')  ORDER BY created_at desc
Mysql2::Error: Unknown column 'events.expiry_date' in 'where clause': SELECT `mobile_applications`.* FROM `mobile_applications` WHERE (events.expiry_date >= '2019-02-18 07:34:40.738517')  ORDER BY created_at desc
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'events.expiry_date' in 'where clause': SELECT `mobile_applications`.* FROM `mobile_applications` WHERE (events.expiry_date >= '2019-02-18 07:34:40.738517')  ORDER BY created_at desc

更新

请建议我如何过滤它。使用 references 也会引发以下错误,并且与 Marek Lipka 提供的答案相同,

ActiveRecord::StatementInvalid: Mysql2::Error: Column 'created_at' in 
order clause is ambiguous: SELECT `mobile_applications`.`id` AS t0_r0, 
`mobile_applications`.`name` AS t0_r1, ...

我想这是由于模型中存在的 default_scope 造成的列歧义导致按 created_at 排序,这在两个关联表中都存在。

默认情况下,includes 不执行 left join,而是执行两个单独的数据库查询。您可以使用 eager_load 强制 left join,如下所示:

MobileApplication.eager_load(:events).where('events.expiry_date >= ?', Time.zone.now)

或者,如果您实际上不需要预先加载(我不知道),您可以简单地使用 joins:

MobileApplication.joins(:events).where('events.expiry_date >= ?', Time.zone.now)

关于使用 referenceseager_load 的错误:您显然尝试在某处按 created_at 进行排序(尽管您没有在问题中包含此内容),例如:

order('created_at DESC')

所以,很明显,DB 不知道 table 你对 joins 有什么想法,因为 mobile_applications 或 [=] 中都有 created_at 列25=]。所以你需要指定'target' table,比如:

order('mobile_applications.created_at DESC')

来自 rails 4.x,您必须添加关键字 references:

MobileApplication.includes(:events).references(:events).where("events.expiry_date >= ?", Time.zone.now)