Rails 有没有好的缓存记忆插件?
我有一个类似以下的模型:
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
我想记住平衡方法并将其存储在内存缓存中。 当然,问题是每次创建付款或购买时,缓存的值都需要过期。 我可以在付款和购买的 after_save 回调中插入代码,以使帐户的缓存余额过期,但在我看来,如果我可以这样说,会更容易理解/维护:
cached_memoize :balance, :depends_on => [:payments, :purchases]
是否有现有的 gem/插件这? 在我开始写自己的文章之前,这是一个好主意吗? 我看到的缺点是,对于正在修改 Purchasing 的dollar_amount方法的人来说,他们需要考虑缓存问题可能不太明显(如果他们无意中引入了对另一个模型的依赖,例如 SubPurchase 或其他模型,那么会把事情搞砸的。)但是由于这并不是非常明显,我认为拥有一个简洁的声明性语法是值得的 - 至少这样当它中断时,很清楚如何修复它。
想法?
编辑:为了回应semanticart的答案,我将更明确地说明我的问题“只需将过期放在相关回调中”方法 - 问题是你最终会在整个代码库中过期 - 它从 after_save 回调开始付款,但也许它是在一个单独的购买观察者中,然后你有多态关联、继承树等。我建议的语法迫使开发人员将所有这些情况保存在一个地方的整齐列表中。 这样,当您收到诸如“用户余额有时不同步并且他们不太确定如何复制问题”之类的错误报告时,就更容易弄清楚发生了什么。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在我看来,你想分叉cache_fu,并添加一个选项,神奇地将 after_saves 撒在依赖记录上。 我发现你的依赖关系在一处。
sounds to me like you want to fork cache_fu, and add an option that magically sprinkles the after_saves across the dependent records. I dig having your dependencies in 1 place.
不确定这是否是您正在寻找的内容,但它可能会有所帮助。
http://railscasts.com/episodes/137-memoization
Not sure this is what you are looking for but it may help.
http://railscasts.com/episodes/137-memoization
我会考虑另一种方法:在帐户上有一个余额字段。 在购买和子购买模型上使用回调(after_save 等)来更新父帐户上的余额字段。 您的平衡仅在其他模型修改时才会改变,您永远不必担心它会过时。
I'd consider another approach: have a balance field on the account. Use callbacks (after_save, etc.) on the Purchase and SubPurchase models to update the balance field on the parent Account. Your balance only changes when the other models are modified and you never have to worry about it being stale.