DVG DVG - 1 year ago 65
Ruby Question

ActiveRecord Reputation System - Only displaying karma for one vote

I have a pretty simple reputation system defined.

class Post < ActiveRecord::Base
has_reputation :votes, :source => :user, :aggregated_by => :sum

def upvote(user)
self.add_or_update_evaluation(:votes, 1, user)

def downvote(user)
self.add_or_update_evaluation(:votes, -1, user)

def score

class User < ActiveRecord::Base
has_reputation :karma,
:source => [:reputation => :votes, :of => :posts, :weight => 10],
:aggregated_by => :sum

def karma

For the most part it works. Users are able to change their votes, upvote or downvote, and score is returned correctly for the posts.

However, when I get a user's karma in the case one of their posts has 2 upvotes, I would expect their karma to be 20, but 10 is returned. Any idea what's wrong here?

Answer Source

Your Post model also needs a :source_of so it knows which other reputations refer to it, so they can be updated:

has_reputation :votes,
  :source => :user,
  :aggregated_by => :sum,
  :source_of => {:reputation => :karma, :of => :user}


If the karma is out of sync with the votes, you can find & delete the karma records for that user, and they'll be regenerated the next time you access them.

user.reputations.where(reputation_name: 'karma')

Some other suggested tweaks:

  • you should define belongs_to :user in Post
  • you should define has_many :posts in User
  • your score method needs to pass the :votes symbol instead of :score