thumbs_up icon indicating copy to clipboard operation
thumbs_up copied to clipboard

Calculating total karma for a user

Open Brotakuu opened this issue 8 years ago • 3 comments

What would be the best way to calculate the total number of votes a user has received? (ie: tally all votes from posts a user created).

Would the best approach be to create a counter that increments everytime a vote is cast? Or is there a built in method that can tally the total?

Brotakuu avatar Mar 14 '17 21:03 Brotakuu

To sum all votes for posts for a particular user: User.find(...).posts.map(&:votes_for).sum

To sum all votes for subtracted from votes against for a particular user, who created posts: User.find(...).posts.map(&:plusminus).sum

If you're doing this often, it would be worthwhile to denormalize this to the User model.

bouchard avatar Mar 14 '17 21:03 bouchard

Thanks, that was exactly what I was looking for. I tried to search online for what you mean by denormalize this to the User model. Would you mind explaining or adding an example?

Do you mean create a method in the model like:

def get_karma
    return self.posts.map(&:votes_for).sum
end

Brotakuu avatar Mar 14 '17 22:03 Brotakuu

By denormalize, I mean you can store the computed value on the User model (if you have lots of posts, would be useful, but not necessary - just for performance reasons).

By the way, you should generally name your methods with adjectives/nouns, not verbs/adverbs, in Ruby convention. A.k.a., not get_karma, but karma.

Something like:

class User
  def votes_for_all_posts
    # Create an integer field `votes_for_all_posts` on User, and make sure
Post has an index on `created_at`.
    if posts.order('created_at ASC').first.created_at > created_at
      v = posts.map(&:votes_for).sum
      write_attribute(:votes_for_all_posts, v)
      v
    else
      read_attribute(:votes_for_all_posts)
    end
  end
end

bouchard avatar Mar 14 '17 22:03 bouchard