我正在尝试从数据库中的每个帖子中获取评论数量。但是,以下内容:
Post.includes(:comments).group("posts.id").count("comments.id")
引发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
有趣的是,用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
但上面的查询排除了所有包含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
答案 0 :(得分:13)
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")
请注意,此解决方案具有优势或实际返回Post对象(使用.count()
在我的Rails 3.2上返回Hash),因此您可以遍历视图中的实际post对象并访问属性{{1} }。
答案 1 :(得分:3)
现在这个问题实际上更简单了:
Comment.joins(:post).group(:post_id).count(:post_id)
这会为您提供{<post_id> => <count of comments>}
答案 2 :(得分:1)
试试这个:
Post.select("COUNT(comments.id) AS count_comments_id, posts.id AS posts_id").
includes(:comments).group("posts.id")
答案 3 :(得分:0)
如果您需要的只是帖子计数的哈希:{post_id1 => cnt1, post_id2 => cnt2, ...}
,那么强制关联的左连接将起作用:
Post.joins("LEFT OUTER JOIN comments on posts.id=comments.post_id").
group("posts.id").count("comments.id")