Rails嵌套连接Activerecord与条件

28

我想写一个带条件的嵌套联接查询。

我现在的查询语句是:

Event.joins(:store => :retailer).where(store: {retailer: {id: 2}})

它会输出以下 SQL 语句:

   SELECT "events".* FROM "events" INNER JOIN "stores" ON "stores"."id" = "events"."store_id" INNER JOIN "retailers" ON "retailers"."id" = "stores"."retailer_id" WHERE "store"."retailer_id" = '---
:id: 2
'

还有以下错误:

SQLite3::SQLException: no such column: store.retailer_id: SELECT "events".* FROM "events" INNER JOIN "stores" ON "stores"."id" = "events"."store_id" INNER JOIN "retailers" ON "retailers"."id" = "stores"."retailer_id" WHERE "store"."retailer_id" = '---
:id: 2
'

系统提示我没有列store.retailer_id,但是我可以运行以下查询并正常工作:

Event.first.store.retailer_id
  Event Load (0.2ms)  SELECT  "events".* FROM "events"   ORDER BY "events"."id" ASC LIMIT 1
  Store Load (0.1ms)  SELECT  "stores".* FROM "stores"  WHERE "stores"."id" = ? LIMIT 1  [["id", 28958]]
=> 4
3个回答

42

看起来您不需要嵌套的连接。尝试使用类似于以下内容:

Event.joins(:store).where(stores: {retailer_id: 2})

使用 stores 也应该可以进行嵌套连接。

Event.joins(:store => :retailer).where(stores: {retailer: {id: 2}})

5
太棒了,我需要使用“stores”而不是“store”... 这很容易解决。谢谢dimuch! - stytown
同 @stytown 所说 - 我花了好几天的时间才意识到,即使我使用了 :has_one 关系,在 where 子句中我仍需要将关联名称变成复数形式。你刚刚救了我的一命。 - stephenmurdoch
请注意,一旦您的表格具有命名空间,这将变得相当丑陋: Event.joins(:store).where("namespace_stores.retailer_id = ?", 2) - alecvn
这个答案至今仍然在拯救我们,已经过去了7年(或者至少刚刚拯救了我)。虽然我不理解这个复数形式的约定,但很高兴Rails在这些年里没有反复改变主意。 - aidan

6
有一种比使用花括号更简单的方法:

使用冒号即可:

Event.joins(:store => :retailer).where('stores.retailer_id => ?', 2)

4
您可以使用以下语法访问 零售商 ID
Event.joins(:store => :retailer).where('retailers.id' => 2)

注:已在Rails 5上进行测试


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接