[英]How do I query amount of child records in Ruby on Rails
I have a many to many relationship between Items
and Categories
. 我在
Items
和Categories
之间有很多关系。
I am trying to pull out the number of items belonging to each category in next format: [category.id, <number of items>]
我正在尝试以下一种格式提取属于每个类别
[category.id, <number of items>]
: [category.id, <number of items>]
Here is what I have so far: 这是我到目前为止的内容:
Category.joins(:items).select('id, count(id) as quantity')
But it doesn't work. 但这是行不通的。 Could anyone help me and point to the right direction?
谁能帮助我并指出正确的方向?
There are multiple problems: 存在多个问题:
id, count(id) as quantity
is ambiguous, categories.id, count(items.id) as quantity
is better id, count(id) as quantity
不明确, categories.id, count(items.id) as quantity
更好 joins
produces INNER JOIN
, but you probably want to use LEFT OUTER JOIN
joins
产生INNER JOIN
,但是您可能要使用LEFT OUTER JOIN
GROUP BY
is not specified GROUP BY
For Ruby on Rails >= 5 you use: 对于Ruby on Rails> = 5,请使用:
categories = Category.select('categories.id, count(items.id) as quantity').
left_outer_joins(:items).
group(:id)
category = categories.first
category.id #=> 12
category.quantity #=> 34
For Ruby on Rails < 5 you replace left_outer_joins(:items)
with: 对于<5的Ruby on Rails,请将
left_outer_joins(:items)
替换为:
joins('left outer join items on items.category_id = categories.id')
A Note About to_sql
关于
to_sql
It may be helpful to know you can call to_sql
on Relation
to view the SQL which is going to be run. 知道您可以在
Relation
上调用to_sql
来查看将要运行的SQL可能会有所帮助。 If you call it against your code you will see: 如果针对您的代码调用它,您将看到:
select id,
count(id) as quantity
from `categories`
inner join `items` ON `items`.`category_id` = `categories`.`id`
Which does not make much sense. 这没有多大意义。 And here is what we get after applying the changes:
这是应用更改后的结果:
select categories.id,
count(items.id) as quantity
from `categories`
left outer join `items` ON `items`.`category_id` = `categories`.`id`
group by `categories`.`id`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.