Skip to content

Instantly share code, notes, and snippets.

@kainosnoema
Last active December 12, 2015 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kainosnoema/4727505 to your computer and use it in GitHub Desktop.
Save kainosnoema/4727505 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 = block ? instance_eval(&block) : __getobj__.send(method_name)
instance_variable_set ivar, val
update_cache
val
end
end
end
klass.class_eval do
def cache_key
send self.class.cache_key
end
def update_cache
Rails.cache.write self.class.cache_key_for(cache_key), self
end
def invalidate_cache
Rails.cache.delete self.class.cache_key_for(cache_key)
end
end
klass
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment