Skip to content

Instantly share code, notes, and snippets.

@ymek
Last active August 29, 2015 14:04
Show Gist options
  • Save ymek/39e1a5169dd773e0f359 to your computer and use it in GitHub Desktop.
Save ymek/39e1a5169dd773e0f359 to your computer and use it in GitHub Desktop.
Cache Keys for ActiveRecord Associations
module Collection
extend ActiveSupport::Concern
included do
def cache_key(updated_at_field = :updated_at)
class_name = self.class.to_s.demodulize.downcase
count = self.count
max_updated_at = self.maximum(updated_at_field).try(:utc).try(:to_s, :number)
"#{class_name}/#{count}/#{max_updated_at}"
end
end
end
module Model
extend ActiveSupport::Concern
included do
def cache_key_for(prefix, collection = [], options = {})
options.reverse_merge!(updated_at_field: :updated_at)
key = "#{prefix}/#{self.cache_key}"
if !collection.is_a?(Array)
collection = [collection]
end
associations, records = collection.partition do |item|
item.is_a?(ActiveRecord::Associations::CollectionProxy)
end
if records.present?
key << cache_keys_to_append(records)
end
if associations.present?
key << associations_cache_key(associations, options[:updated_at_field])
end
key
end
private
def associations_cache_key(associations, updated_at_field)
associations.collect { |association|
association.cache_key(updated_at_field).prepend('/')
}.join
end
def cache_keys_to_append(records)
records.collect { |record|
record.cache_key.prepend('/')
}.join
end
end
end
class Example < ActiveRecord::Base
has_many :other_things
has_one :thing
def cache_key_for_other_things
cache_key_for('other_things_partial', self.other_things)
end
def cache_key_for_thing_and_other_things
cache_key_for('crazy_partial', [self.thing, self.other_things])
end
end
ActiveRecord::Base.class_eval do
include Model
end
ActiveRecord::Associations::CollectionProxy.class_eval do
include Collection
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment