Question

I’m using acts_as_votable and devise_invitable in my rails app.

Users can comment and their comments are votable.

Each user has a karma/score

Currently I am showing users karma on their profiles. I don’t actually have their scores saved in the database. I am just calculating it by using this:

<% comment_vote_count = current_user.comments.map{|c| c.votes.count}.sum
   comment_vote_count ||=0 
   comment_vote_count *= 2
   total_vote_count = comment_vote_count + current_user.base_score %>

base_score acts as an anchor that can manually be changed.

I’m looking to add something to the scoring mechanism. I would like to add 10 points to any given user for each user they invite that actually accepts the invite and signs up.

So the new logic for calculating the users karma should be, the number of votes received on comments times two, plus 10 points for every successful invitation, plus the base score.

More importantly how do I save this in the database? I would like to add a column to the users table called score. But how do I get it to update? Do I get the controller to update it every time the user loads their profile?

Was it helpful?

Solution

Here is a simple plan. First, add a score column to your users table.

In your User model:

after_invitation_accepted :increment_score_of_inviter

def increment_score_of_inviter
  invitation_by.increment!(:score, 10)
end

def comment_vote_count
  Vote.find(comment_ids).count * 2
end

def calculated_vote_count
  base_score + comment_vote_count
end

def recalculate_score!
  update_attribute(:score, calculated_vote_count)
end

See devise's invitation callbacks about after_invitation_accepted

This could be quite inefficient if you have a lot of voting activity, but to keep the score column updated, add this to your Vote model:

after_create :increment_user_score

def increment_user_score
  user.increment!(:score, 2)
end

An alternative here would be to periodically recalculate the score column, perhaps using whenever gem:

every :hour do
  User.find_each { |u| u.recalculate_score! }
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top