У меня есть модель в соответствии с:
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
Я хочу запомнить метод баланса и сохранить его в memcached. Проблема, конечно же, заключается в том, что значение кэшированного значения должно истекать каждый раз, когда создается платеж или покупка. Я мог бы вставить код в обратные вызовы after_save платежей и покупок, чтобы истечь кэшированные остатки на их счетах, но мне кажется, что было бы легче понять / поддержать, если бы я мог сказать что-то вроде:
cached_memoize :balance, :depends_on => [:payments, :purchases]
Существует ли существующий гем / плагин, который делает это? И прежде чем я уйду и напишу свое, это хорошая идея? Недостаток, который я вижу, состоит в том, что для тех, кто модифицирует метод dollar_amount службы Purchase, может быть менее очевидно, что им необходимо учитывать проблему кэширования (если они невольно вводят зависимость от другой модели, например, SubPurchase или чего-то еще, все испортило бы.) Но так как в любом случае это не супер очевидно, я думаю, что наличие аккуратного декларативного синтаксиса того стоит - по крайней мере, когда он ломается, ясно, как это исправить.
Мысли
Edit: в ответ на ответ semanticart я более подробно расскажу о моей проблеме с подходом «просто поместите expires в соответствующий обратный вызов» - проблема в том, что вы заканчиваете expires по всей базе кода - он начинается с обратный вызов after_save для оплаты, но, возможно, он находится в отдельном наблюдателе для покупок, и затем у вас возникают полиморфные ассоциации, деревья наследования и т. д. Синтаксис, который я предлагаю, заставляет разработчиков хранить все эти случаи в аккуратном списке в одном месте. Таким образом, когда вы получаете отчет об ошибке типа «Балансы пользователей иногда не синхронизированы, и они не совсем уверены, как воспроизвести проблему», гораздо проще понять, что происходит.