计算Rails中的相关记录

Giu*_*ppe 10 mysql activerecord ruby-on-rails

我试图从数据库中的每个帖子中获取评论的数量.但是,以下内容:

Post.includes(:comments).group("posts.id").count("comments.id")
Run Code Online (Sandbox Code Playgroud)

引发mysql错误"Unknown column comments.id",因为生成的sql似乎完全忽略了includes():

SELECT COUNT(comments.id) AS count_comments_id, posts.id AS posts_id
FROM `posts` GROUP BY posts.id
Run Code Online (Sandbox Code Playgroud)

有趣的是,用join()替换includes()将产生有效的sql:

Post.joins(:comments).group("posts.id").count("comments.id")

SELECT COUNT(comments.id) AS count_comments_id, posts.id AS posts_id
FROM `posts` INNER JOIN `comments` ON `comments`.`post_id` = `posts`.`id`
GROUP BY posts.id
Run Code Online (Sandbox Code Playgroud)

但上面的查询排除了所有0条评论的帖子,这不是我想要的.我需要的是生成以下SQL(但没有编写SQL,他是他)

SELECT COUNT(comments.id) AS count_comments_id, posts.id AS posts_id
FROM `posts` LEFT OUTER JOIN `comments` ON `comments`.`post_id` = `posts`.`id`
GROUP BY posts.id
Run Code Online (Sandbox Code Playgroud)

Tig*_*ine 15

includes方法不会在所有情况下都进行连接,而是出于性能原因批量获取关联(请参阅Rails:include vs.:joins).

你需要做的是一个连接,你几乎在正确的路径上,但得到组子句有点错误:

Post.select("posts.*, COUNT(comments.id) as comment_count").joins("LEFT OUTER JOIN comments ON (comments.post_id = posts.id)").group("posts.id")
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案具有优势或实际返回Post对象(使用.count()在我的Rails 3.2上返回Hash),因此您可以在视图中循环实际的post对象并访问该属性comment_count.


Pet*_* P. 7

如今,这个问题实际上更简单:

Comment.joins(:post).group(:post_id).count(:post_id)
Run Code Online (Sandbox Code Playgroud)

这会给你一张地图 {<post_id> => <count of comments>}