lib/cacheable.rb in simple_cacheable-1.3.2 vs lib/cacheable.rb in simple_cacheable-1.3.3

- old
+ new

@@ -1,273 +1,24 @@ require 'uri' +require "cacheable/caches" +require "cacheable/keys" +require "cacheable/expiry" module Cacheable def self.included(base) - base.class_eval do - class << self - def model_cache(&block) - class_attribute :cached_key, - :cached_indices, - :cached_methods, - :cached_class_methods, - :cached_associations - instance_exec &block - end + base.extend(Cacheable::Caches) + base.send :include, Cacheable::Keys + base.send :include, Cacheable::Expiry - def with_key - self.cached_key = true - - class_eval <<-EOF - after_commit :expire_key_cache, :on => :update - - def self.find_cached(id) - Rails.cache.fetch "#{name.tableize}/" + id.to_i.to_s do - self.find(id) - end - end - EOF - end - - def with_attribute(*attributes) - self.cached_indices = attributes.inject({}) { |indices, attribute| indices[attribute] = {} } - - class_eval <<-EOF - after_commit :expire_attribute_cache, :on => :update - after_commit :expire_all_attribute_cache, :on => :update - EOF - - attributes.each do |attribute| - class_eval <<-EOF - def self.find_cached_by_#{attribute}(value) - self.cached_indices["#{attribute}"] ||= [] - self.cached_indices["#{attribute}"] << value - Rails.cache.fetch attribute_cache_key("#{attribute}", value) do - self.find_by_#{attribute}(value) - end - end - - def self.find_cached_all_by_#{attribute}(value) - self.cached_indices["#{attribute}"] ||= [] - self.cached_indices["#{attribute}"] << value - Rails.cache.fetch all_attribute_cache_key("#{attribute}", value) do - self.find_all_by_#{attribute}(value) - end - end - EOF - end - end - - def with_method(*methods) - self.cached_methods = methods - - class_eval <<-EOF - after_commit :expire_method_cache, :on => :update - EOF - - methods.each do |meth| - class_eval <<-EOF - def cached_#{meth} - Rails.cache.fetch method_cache_key("#{meth}") do - #{meth} - end - end - EOF - end - end - - # Cached class method - # Should expire on any instance save - def with_class_method(*methods) - self.cached_class_methods = methods - - class_eval <<-EOF - after_commit :expire_class_method_cache, on: :update - EOF - - methods.each do |meth| - class_eval <<-EOF - def self.cached_#{meth} - Rails.cache.fetch class_method_cache_key("#{meth}") do - #{meth} - end - end - EOF - end - - end - - def with_association(*association_names) - self.cached_associations = association_names - - association_names.each do |association_name| - association = reflect_on_association(association_name) - - if :belongs_to == association.macro - polymorphic = association.options[:polymorphic] - polymorphic ||= false - class_eval <<-EOF - def cached_#{association_name} - Rails.cache.fetch belong_association_cache_key("#{association_name}", #{polymorphic}) do - #{association_name} - end - end - EOF - else - if through_reflection_name = association.options[:through] - through_association = self.reflect_on_association(through_reflection_name) - - # FIXME it should be the only reflection but I'm not 100% positive - reverse_through_association = through_association.klass.reflect_on_all_associations(:belongs_to).first - - # In a through association it doesn't have to be a belongs_to - reverse_association = association.klass.reflect_on_all_associations(:belongs_to).find { |reverse_association| - reverse_association.options[:polymorphic] ? reverse_association.name == association.source_reflection.options[:as] : reverse_association.klass == self - } - - if reverse_association - association.klass.class_eval <<-EOF - after_commit :expire_#{association_name}_cache - - def expire_#{association_name}_cache - if respond_to? :cached_#{reverse_association.name} - # cached_viewable.expire_association_cache - cached_#{reverse_association.name}.expire_association_cache(:#{association_name}) - else - #{reverse_association.name}.#{reverse_through_association.name}.expire_association_cache(:#{association_name}) - end - end - EOF - end - elsif :has_and_belongs_to_many == association.macro - # No such thing as a polymorphic has_and_belongs_to_many - reverse_association = association.klass.reflect_on_all_associations(:has_and_belongs_to_many).find { |reverse_association| - reverse_association.klass == self - } - - association.klass.class_eval <<-EOF - after_commit :expire_#{association_name}_cache - - def expire_#{association_name}_cache - if respond_to? :cached_#{reverse_association.name} - # cached_viewable.expire_association_cache - cached_#{reverse_association.name}.expire_association_cache(:#{association_name}) - else - #{reverse_association.name}.each do |assoc| - assoc.expire_association_cache(:#{association_name}) - end - end - end - EOF - else - reverse_association = association.klass.reflect_on_all_associations(:belongs_to).find { |reverse_association| - reverse_association.options[:polymorphic] ? reverse_association.name == association.options[:as] : reverse_association.klass == self - } - - association.klass.class_eval <<-EOF - after_commit :expire_#{association_name}_cache - - def expire_#{association_name}_cache - if respond_to? :cached_#{reverse_association.name} - cached_#{reverse_association.name}.expire_association_cache(:#{association_name}) - else - #{reverse_association.name}.expire_association_cache(:#{association_name}) - end - end - EOF - end - class_eval <<-EOF - def cached_#{association_name} - Rails.cache.fetch have_association_cache_key("#{association_name}") do - #{association_name}.respond_to?(:all) ? #{association_name}.all : #{association_name} - end - end - EOF - end - end - end - - def attribute_cache_key(attribute, value) - "#{name.tableize}/attribute/#{attribute}/#{URI.escape(value.to_s)}" - end - - def all_attribute_cache_key(attribute, value) - "#{name.tableize}/attribute/#{attribute}/all/#{URI.escape(value.to_s)}" - end - - def class_method_cache_key(meth) - "#{name.tableize}/class_method/#{meth}" - end - + base.class_eval do + def self.model_cache(&block) + class_attribute :cached_key, + :cached_indices, + :cached_methods, + :cached_class_methods, + :cached_associations + instance_exec &block end - end - end - def expire_model_cache - expire_key_cache if self.class.cached_key - expire_attribute_cache if self.class.cached_indices.present? - expire_all_attribute_cache if self.class.cached_indices.present? - expire_method_cache if self.class.cached_methods.present? - expire_class_method_cache if self.class.cached_class_methods.present? - - if self.class.cached_associations.present? - self.class.cached_associations.each do |assoc| - expire_association_cache(assoc) - end - end - end - - def expire_key_cache - Rails.cache.delete model_cache_key - end - - def expire_attribute_cache - self.class.cached_indices.each do |attribute, values| - value = self.send(attribute) - Rails.cache.delete self.class.attribute_cache_key(attribute, value) - end - end - - def expire_all_attribute_cache - self.class.cached_indices.each do |attribute, values| - value = self.send(attribute) - Rails.cache.delete self.class.all_attribute_cache_key(attribute, value) - end - end - - def expire_method_cache - self.class.cached_methods.each do |meth| - Rails.cache.delete method_cache_key(meth) - end - end - - def expire_class_method_cache - self.class.cached_class_methods.each do |meth| - Rails.cache.delete self.class.class_method_cache_key(meth) - end - end - - def expire_association_cache(name) - Rails.cache.delete have_association_cache_key(name) - end - - def model_cache_key - "#{self.class.name.tableize}/#{self.id.to_i}" - end - - def method_cache_key(meth) - "#{model_cache_key}/method/#{meth}" - end - - def belong_association_cache_key(name, polymorphic=nil) - if polymorphic - "#{self.send("#{name}_type").tableize}/#{self.send("#{name}_id")}" - else - "#{name.tableize}/#{self.send(name + "_id")}" - end - end - - def have_association_cache_key(name) - "#{model_cache_key}/association/#{name}" - end end