Matthew Berman
Matthew Berman

Reputation: 8631

How do I add a counter total to my user model based on another table?

I have users that have many points and points belongs to users.

Points can be any amount.

I want to be kind to my db by adding a total points cache to my user model so I can easily just do user.total_points

how do I go about implementing this?

EDIT: PS I am adding points for the first time so there's no need to go back and calculate points that users may have already earned...just need it going forward

Upvotes: 0

Views: 129

Answers (1)

Harish Shetty
Harish Shetty

Reputation: 64363

You can use the counter_cache technique if row in the points table constitutes one point. Otherwise you can implement it using a simple after_save filter.

class User
  # add a column called total_points and set the default to 0    
  has_many :points    
end


class Point

  # assuming `amount` column stores the points.    
  belongs_to :user

  after_create { |p| p.update_user_points(:create) }
  after_update { |p| p.update_user_points(:update) if p.amount_changed? }
  after_destroy{ |p| p.update_user_points(:destroy)}

  def update_user_points(type)
    delta = (type == :create) ? amount :
               (type == :update) ? (amount - amount_was) :
                 -amount
    User.update_counters(user, :total_points => delta) 
  end

end

Upvotes: 1

Related Questions