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
  • Select an option

  • Save stephencelis/4727608 to your computer and use it in GitHub Desktop.

Select an option

Save stephencelis/4727608 to your computer and use it in GitHub Desktop.

Revisions

  1. stephencelis revised this gist Feb 7, 2013. 2 changed files with 17 additions and 15 deletions.
    1 change: 0 additions & 1 deletion cached_account.rb
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,6 @@ class CachedAccount < CachedDelegateClass(Recurly::Account)
    cache(:subscription) { subscriptions.live.first }
    cache(:add_ons) { subscription.try(:add_ons).to_a }
    cache(:plan) { subscription.try :plan }
    cache(:invoices) { invoices.to_a }
    cache(:balance) {
    BigDecimal('0.01') * invoices.past_due.map(&:total_in_cents).sum
    }
    31 changes: 17 additions & 14 deletions cached_delegate_class.rb
    Original file line number Diff line number Diff line change
    @@ -1,31 +1,34 @@
    def CachedDelegateClass(superclass)
    klass = DelegateClass(superclass)
    def CachedDelegateClass(superklass)
    klass = DelegateClass(superklass)

    klass.instance_eval <<-RUBY
    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 #{superclass.to_s.tableize}
    args.map(&:to_s).join('/')
    args.unshift delegate_class.name.tableize
    args.map(&:to_s).join '/'
    end

    cattr_accessor :cache_key
    self.cache_key = :uuid
    private

    def cache_constructor method_name
    define_singleton_method method_name do |*args|
    Rails.cache.fetch cache_key_for(*args) do
    new(#{superclass}.send(method_name, *args))
    new(delegate_class.send(method_name, *args))
    end
    end
    end

    def cache method_name, &block
    ivar = "@_\#{method_name.to_s.gsub /\W/, ''}"
    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
    __getobj__.instance_eval(&block)
    instance_eval(&block)
    else
    __getobj__.send(method_name)
    end
    @@ -34,17 +37,17 @@ def cache method_name, &block
    val
    end
    end
    RUBY
    end

    klass.module_eval do
    klass.class_eval do
    def cache_key
    send self.class.cache_key
    end

    private

    def recache
    Rails.cache.write self.class.cache_key_for(to_param), self
    Rails.cache.write self.class.cache_key_for(cache_key), self
    end
    end

  2. @kainosnoema kainosnoema revised this gist Feb 7, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cached_delegate_class.rb
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@ def CachedDelegateClass(superclass)

    klass.instance_eval <<-RUBY
    def cache_key_for *args
    args.unshift superclass.to_s.tableize
    args.unshift #{superclass.to_s.tableize}
    args.map(&:to_s).join('/')
    end
  3. @kainosnoema kainosnoema revised this gist Feb 7, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cached_delegate_class.rb
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ def cache method_name, &block
    RUBY

    klass.module_eval do
    def to_param
    def cache_key
    send self.class.cache_key
    end

  4. @kainosnoema kainosnoema revised this gist Feb 7, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cached_account.rb
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    class Account < CachedDelegateClass(Recurly::Account)
    class CachedAccount < CachedDelegateClass(Recurly::Account)
    self.cache_key = :account_code

    cache_constructor :find
  5. @kainosnoema kainosnoema renamed this gist Feb 7, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. @kainosnoema kainosnoema created this gist Feb 7, 2013.
    14 changes: 14 additions & 0 deletions account.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    class Account < 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(:invoices) { invoices.to_a }
    cache(:balance) {
    BigDecimal('0.01') * invoices.past_due.map(&:total_in_cents).sum
    }
    end
    52 changes: 52 additions & 0 deletions cached_delegate_class.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    def CachedDelegateClass(superclass)
    klass = DelegateClass(superclass)

    klass.instance_eval <<-RUBY
    def cache_key_for *args
    args.unshift superclass.to_s.tableize
    args.map(&:to_s).join('/')
    end
    cattr_accessor :cache_key
    self.cache_key = :uuid
    private
    def cache_constructor method_name
    define_singleton_method method_name do |*args|
    Rails.cache.fetch cache_key_for(*args) do
    new(#{superclass}.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
    __getobj__.instance_eval(&block)
    else
    __getobj__.send(method_name)
    end
    instance_variable_set ivar, val
    recache
    val
    end
    end
    RUBY

    klass.module_eval do
    def to_param
    send self.class.cache_key
    end

    private

    def recache
    Rails.cache.write self.class.cache_key_for(to_param), self
    end
    end

    klass
    end