2012-06-18 95 views
4

我想從數據庫中的每個帖子獲取評論數。然而以下,:計算Rails中的關聯記錄

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

引發MySQL錯誤 「未知列comments.id」 時,由於生成的sql似乎完全忽略包括():

SELECT COUNT(comments.id) AS count_comments_id, posts.id AS posts_id 
FROM `posts` GROUP BY posts.id 

有趣的是,取代包括()與連接()會產生工作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 

回答

9

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") 

注意,該解決方案具有效益或實際返回後對象(使用.count()在我的Rails 3.2中返回一個Hash),這樣你就可以在視圖中循環實際的後期對象,並且還可以訪問屬性comment_count

+0

正確,但INNER JOIN排除了所有沒有評論的帖子。我需要的是完整的帖子列表,計算的字段(即comment_count)在適當的情況下設置爲0 – Giuseppe

+0

請查看我自己的答案以瞭解我的意思。將明確的LEFT JOIN添加到您的解決方案似乎不起作用。所有帶有0條評論的結果都彙總爲一條,不知道爲什麼。 – Giuseppe

+0

因爲它是由comments.id分組的。由於所有沒有評論的評論都有評論。只需將group子句更改爲'posts.id',它應該沒問題。 我更新了答案 – Tigraine

1

試試這個:

Post.select("COUNT(comments.id) AS count_comments_id, posts.id AS posts_id"). 
    includes(:comments).group("posts.id") 
+0

你有一個錯字:includes(:comments) – Giuseppe

+0

這只是返回一個post模型數組,而sel ect子句被忽略(在生成的查詢中沒有COUNT) – Giuseppe

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") 
0

這個問題實際上是這樣簡單的時下:

Comment.joins(:post).group(:post_id).count(:post_id) 

這會給你一個地圖{<post_id> => <count of comments>}