ActiveRecord :: StatementInvalid:Mysql2 :: Error:使用include时,“ where”查询的未知列

时间:2019-02-18 07:42:00

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我有以下关联:

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对其进行了排序。

2 个答案:

答案 0 :(得分:2)

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

eager_load

或者,如果您实际上不需要急切加载(我不知道),则可以简单地使用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

因此,显然,DB不知道您打算使用order('created_at DESC') 使用哪个表,因为joinscreated_at中都有mobile_applications列。因此,您需要指定“目标”表,例如:

events

答案 1 :(得分:0)

在rails 4.x中,您必须添加关键字references

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