module LaserLemon module CacheFlow def self.included(base) base.class_eval do class_inheritable_accessor :cache_serialization self.cache_serialization = false extend ClassMethods include InstanceMethods alias_method_chain :to_xml, :cache_flow alias_method_chain :to_json, :cache_flow end end module ClassMethods def cache_flow(value = true) if block_given? old_value = cache_serialization begin self.cache_serialization = value yield ensure self.cache_serialization = old_value end else self.cache_serialization = value end end end module InstanceMethods def to_xml_with_cache_flow(options = {}) with_cache_flow(:xml, options) do to_xml_without_cache_flow(options) end end def to_json_with_cache_flow(options = {}) with_cache_flow(:json, options) do to_json_without_cache_flow(options) end end private def with_cache_flow(extension, options, &block) if options.has_key?(:cache) ? options.delete(:cache) : self.class.cache_serialization options.merge!(:cache => false) key = send("#{extension}_cache_key", options) Rails.cache.fetch(key){ yield } else yield end end def xml_cache_key(options) serialized_cache_key(:xml, options.except(:builder)) end def json_cache_key(options) serialized_cache_key(:json, options) end def serialized_cache_key(extension, options) ["#{cache_key}.#{extension}", options.except(:cache).to_query].delete_if(&:blank?).join('?') end end end end ActiveRecord::Base.send(:include, LaserLemon::CacheFlow)