You could store this information in the database instead of recalculating it, using:
- Counter caching
- Custom callbacks
Counter Caching
As an example, if measuring the number of badges, you could create a database field in User
called badges_count
, then in the Badge model, have belongs_to :user, :counter_cache => true
. Now, whenever the number of badges changes, you can access the count without any new calculations at @user.badges_count
.
A basic implementation: http://asciicasts.com/episodes/23-counter-cache-column
Custom Callbacks
Let's say you have a field that measures behavior that is more complex than a simple count. In this case, just implement callbacks that update a field whenever a certain action occurs using before_save
, after_save
, before_create
, etc.
Concerns about Inconsistency
Storing the data in your database will only be inconsistent if you're doing it wrong. There are a finite number of paths through which any statistic can be updated, and you should ensure that all paths are covered in updating whichever field you are using. Rails does it for you with counter_caching, and you have to do it yourself if you use custom callbacks or you have some unusual situation.