16

データベース内の各投稿からコメント数を取得しようとしています。ただし、次のとおりです。

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

生成された sql が includes() を完全に無視しているように見えるため、mysql エラー「Unknown column comments.id」が発生します。

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

興味深いことに、includes() を joins() に置き換えると、動作する 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
4

5 に答える 5

19

メソッドはすべてのincludes場合に結合を行うわけではなく、パフォーマンス上の理由から関連付けをバッチフェッチします ( Rails :include と :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 で return a Hash を使用する) という利点があるため、ビュー内の実際の post オブジェクトをループして、プロパティにアクセスすることもできますcomment_count

于 2012-06-18T08:02:00.820 に答える
10

この問題は、今日では実際にはずっと簡単です。

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

これにより、のマップが表示されます{<post_id> => <count of comments>}

于 2017-11-30T05:44:11.173 に答える
2

これを試して:

Post.select("COUNT(comments.id) AS count_comments_id, posts.id AS posts_id").
  includes(:comments).group("posts.id")
于 2012-06-18T06:12:52.527 に答える
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")
于 2012-06-19T06:36:39.063 に答える