Skip to content

Instantly share code, notes, and snippets.

@bschaeffer
Last active December 21, 2015 22:19
Show Gist options
  • Select an option

  • Save bschaeffer/6374553 to your computer and use it in GitHub Desktop.

Select an option

Save bschaeffer/6374553 to your computer and use it in GitHub Desktop.
Simple, simple method caching for ActiveRecord models

Cacheable

Simple, simple method caching for ActiveRecord models.

Example

class User < ActiveRecord::Base
  include Cacheable
  
  def related_events
    Event.expensive_relationships_finder_for(self)
  end
  cache_method :related_events, to_a: true
end

Options

  • :key - Optional time column to use for the cache_key method. Must respond to utc.to_s(:number)
  • :to_a - Should we call to_a on the results?
module Cacheable
extend ActiveSupport::Concern
module ClassMethods
def cache_method(method, options={})
opts = {key: :updated_at, to_a: false}.merge(options)
define_method "fetch_#{method}" do
fetch_key = [cache_key(opts[:key]), method]
Rails.cache.fetch(fetch_key) do
results = self.send(method)
if opts[:to_a] && results.respond_to?(:to_a)
results.to_a
else
results
end
end
end
end
end
def cache_key(attribute=:updated_at)
case
when new_record?
"#{self.class.model_name.cache_key}/new"
when timestamp = self[attribute]
timestamp = timestamp.utc.to_s(:number)
"#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
else
"#{self.class.model_name.cache_key}/#{id}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment