I have a model along the lines of:
class Account < ActiveRecord::Base
has_many :payments
has_many :purchases
def balance
payments.sum(:dollar_amount) - purchases.map{|p| p.dollar_amount}.sum
end
end
I want to memoize the balance method and store it in memcached. The problem, of course, is that the cached value needs to get expired any time a payment or purchase is created. I could insert code in the after_save callbacks of payments and purchases to expire the cached balances of their accounts but it seems to me that it would be easier to understand/maintain if I could say something like:
cached_memoize :balance, :depends_on => [:payments, :purchases]
Is there an existing gem/plugin that does this? And before I go off and write my own, is it a good idea? The downside that I see is that it might make it less obvious to somebody who is modifying the dollar_amount method of Purchase that they need to take into account a caching issue (if they unwittingly introduced a dependency on another model, like SubPurchase or something, it would screw things up.) But since this isn't super obvious anyway, I think that having a neat declarative syntax is worth it - at least that way when it breaks, it's clear how to fix it.
Thoughts?
Edit: in response to semanticart's answer I will be more explicit about my problem with the "just put the expires in the relevant callback" approach - the problem is that you end up with expires all over the codebase - it starts with the after_save callback on payment, but maybe it's in a separate observer for purchases, and then you have polymorphic associations, inheritance trees, etc. The syntax I'm proposing forces developers to keep all these cases in a neat list in one place. That way when you get a bug report like "users balances sometimes are out of sync and they aren't quite sure how to replicate the issue" it is a lot easier to figure out what is going on.