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