Skip to content

Instantly share code, notes, and snippets.

@stephencelis
Forked from kainosnoema/cached_account.rb
Created February 7, 2013 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephencelis/4727608 to your computer and use it in GitHub Desktop.
Save stephencelis/4727608 to your computer and use it in GitHub Desktop.
class CachedAccount < CachedDelegateClass(Recurly::Account)
self.cache_key = :account_code
cache_constructor :find
cache(:billing_info)
cache(:subscription) { subscriptions.live.first }
cache(:add_ons) { subscription.try(:add_ons).to_a }
cache(:plan) { subscription.try :plan }
cache(:balance) {
BigDecimal('0.01') * invoices.past_due.map(&:total_in_cents).sum
}
end
def CachedDelegateClass(superklass)
klass = DelegateClass(superklass)
klass.class_attribute :delegate_class
klass.delegate_class = superklass
klass.class_attribute :cache_key
klass.cache_key = :uuid
class << klass
def cache_key_for *args
args.unshift delegate_class.name.tableize
args.map(&:to_s).join '/'
end
private
def cache_constructor method_name
define_singleton_method method_name do |*args|
Rails.cache.fetch cache_key_for(*args) do
new(delegate_class.send(method_name, *args))
end
end
end
def cache method_name, &block
ivar = "@_#{method_name.to_s.gsub /\W/, ''}"
define_method method_name do
return instance_variable_get ivar if instance_variable_defined? ivar
val = if block
instance_eval(&block)
else
__getobj__.send(method_name)
end
instance_variable_set ivar, val
recache
val
end
end
end
klass.class_eval do
def cache_key
send self.class.cache_key
end
private
def recache
Rails.cache.write self.class.cache_key_for(cache_key), self
end
end
klass
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment