2015-02-05 106 views
0

有文章和评论。计数的评论者数

class Comment < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :article, counter_cache: true 
end 

你可以做这样的事情算评论数: @ article.comments_count

的问题是 - 你会怎么算谁留在一个特定的@article评论独特的用户数? (注意:一个唯一的用户可以将多评论)

这里有一个场景:

  1. 评论 - USER_ID(1)
  2. 评论 - USER_ID(4)
  3. 评论 - USER_ID(1 )

评论数= 3
评议人(谁给出了评语独特的用户)数= 2

回答

3

Rails有精彩distinct query method这使得这个特定的查询很容易产生:

Comment.where(article_id: article.id).select(:user_id).distinct.count 

生成的SQL语句:

SELECT DISTINCT COUNT(DISTINCT "comments"."user_id") FROM "comments" WHERE "comments"."article_id" = ? 

的好处这种方法的目的是允许数据库完成繁重的工作。数据库通常会比在Ruby中直接操作对象快几个数量级。

如果你愿意修改Article类,如下所示:

class Article < ActiveRecord::Base 
    has_many :comments 
    has_many :commenters, through: :comments, source: :user 
    has_many :unique_commenters, -> { distinct }, through: :comments, source: :user 
end 

你也可以使用下面的代码来生成一个查询:

article.unique_commenters 

生成以下SQL:

SELECT DISTINCT "users".* FROM "users" INNER JOIN "comments" ON "users"."id" = "comments"."user_id" WHERE "comments"."article_id" = ? 
-1

你可以使用Ruby的Set这个:

unique_commenters = Set.new 

comments.each do |comment| 
    unique_commenters.add comment.user 
end 

unique_commenters.to_a 

你也可以只做到commenters.uniq!的收集,但我想这是低效率的。

1

尝试使用pluckuniq

@article.comments.uniq.pluck(:user_id)

或只是pluck

@article.comments.pluck("DISTINCT user_id")

0
article.comments.collect(&:user).uniq{|user| user.id}.count 
-1

我所知道的最好的方法是创建一个范围:

class Comment 
    belongs_to :user 
    belongs_to :article, counter_cache: true 

    scope :count_by_user ->(user) { where(user_id: user.id).count } 
end 

然后:

@article.comments.count_by_user(user) # 2