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)
关于使用 references
或 eager_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)
我有以下联想:
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)
关于使用 references
或 eager_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)