簡體   English   中英

在 Rails 中計算關聯記錄

[英]Counting associated records in Rails

我正在嘗試從數據庫中的每個帖子中獲取評論數。 但是,以下內容:

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

引發mysql錯誤“未知列comments.id”,因為生成的sql似乎完全忽略了includes():

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

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 上返回一個 Hash),因此您可以循環查看視圖中的實際 post 對象並訪問屬性comment_count

現在這個問題實際上要簡單得多:

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

這將為您提供{<post_id> => <count of comments>}的地圖

嘗試這個:

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

如果您只需要帖子計數的散列: {post_id1 => cnt1, post_id2 => cnt2, ...}那么在關聯上強制左連接將起作用:

  Post.joins("LEFT OUTER JOIN comments on posts.id=comments.post_id").
  group("posts.id").count("comments.id")

對於rails 5 或更高版本,我們有一個 activerecord 方法left_outer_joins我們不需要手動編寫連接邏輯。

Post.left_outer_joins(:comments)
    .distinct
    .select('posts.*, COUNT(comments.*) AS comments_count')
    .group('posts.id')

產生:

SELECT DISTINCT posts.*, COUNT(comments.*) AS comments_count FROM posts 
LEFT OUTER JOIN comments ON comments.post_id = posts.id GROUP BY posts.id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM