2017-10-19 124 views
0

让我解释标题。Rails 5 - ActiveRecord - 过滤与包含has_many的关系,不排除空值

我有一个的has_many模型B.

我想日期的年份和月份过滤B型,同时显示所有的模型A的

因此,例如模型答:

A1 - > 3烧烤

A2 - > 0烧烤

A3 - >图1B

这是我现在的查询:

A.includes(:b_relation) 
.where("extract(month from b.date) = #{month}").references(:b_relation) 
.where("extract(year from b.date) = #{year}").references(:b_relation) 
.all 

它的工作原理!但它只给了我至少有一个B的A,没有的A没有表现出来。

如何使查询包含没有任何B的模型A?

回答

1

您现在正在执行的查询使用的是INNER JOIN,它将排除A中没有关联B s的记录。你想要的是LEFT OUTER JOIN -aka a LEFT JOIN。左连接包括父表中的所有行,无论是否存在关联表中的任何关联记录。

我总是觉得这个形象很有用可视化的SQL连接类型:

enter image description here

滑轨5具有left_outer_joinsmethod这个(别名:left_joins):

A.left_outer_joins(:b_relation) 

在早期版本的Rails,它更手动(我只是在这里编写表名):

A.joins('LEFT OUTER JOIN "bs" ON "bs"."a_id" = "as"."id"') 
+0

如果我查看执行的查询,它会执行LEFT OUTER JOIN,因为内部包含将决定使用'eager_load'ActiveRecord方法。它已经使用了LEFT OUTER JOIN – Lokuzt

+0

你可以分享你的AR查询生成的SQL吗? – hoffm

+0

像这样 选择 “A”, “ID” AS t0_r0, - 。A柱 “B”, “ID” AS t1_r0, - B柱 从 “A” LEFT OUTER JOIN “B” ON“B”。“a_id”=“A”。“id” WHERE“A”。“deleted_at”IS NULL \t AND“A”。“blabla_id”='cfa7e8a8-5566-4ce7-bcbc-05cf420cf7d1' (提取(月份FROM B.date)= 10) \t AND(Extract(year FROM B.date)= 2017)或者B.date IS NULL) \t – Lokuzt