Search code examples
ruby-on-rails-3cachingcounter-cache

How can I cache a calculated attribute in Rails 3 similar to counter_cache?


I have an attribute that is a calculated value based data from various other models.

I am looking for a slick way to cache that value similar to counter_cache but where the value is updated automatically via a custom function. I already have the custom function in the model.

I need to call this function if any of the dependent data is modified. Any suggestions?


Solution

  • Edit, based on comment:

    Ok, so you've got a Like model and a User model. Put the function to update popularity in a method in User, then an after_create or after_save (if it can change after creation) callback on Like to trigger it for the User who received it:

    class User < ActiveRecord::Base
      has_many :likes
    
      def calculate_popularity
        update_attribute(:popularity, existing_function(foo))
      end
    end
    
    class Like < ActiveRecord::Base
      belongs_to :user
    
      after_create :update_user_popularity
    
      def update_user_popularity
        user.calculate_popularity
      end
    end
    

    Obviously, if what receives Likes is various sorts of user activity, rather than the user themselves, you'll need to dig down through your associations to reach the user from the Like, but that shouldn't be too hard.