Module: Cacheable

Defined in:
lib/cacheable.rb,
lib/cacheable/version.rb

Constant Summary collapse

VERSION =
"1.1.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cacheable.rb', line 2

def self.included(base)
  base.class_eval do
    class <<self
      def model_cache(&block)
        instance_exec &block
      end

      def with_key
        class_eval "          after_update :expire_key_cache\n\n          def self.find_cached(id)\n            Rails.cache.fetch \"\#{name.tableize}/\" + id.to_i.to_s do\n              self.find(id)\n            end\n          end\n        EOF\n      end\n\n      def with_attribute(*attributes)\n        class_eval <<-EOF\n          after_update :expire_attribute_cache\n        EOF\n\n        write_inheritable_attribute :cached_indices, attributes.inject({}) { |indices, attribute| indices[attribute] = {} }\n        attributes.each do |attribute|\n          class_eval <<-EOF\n            def self.find_cached_by_\#{attribute}(value)\n              indices = read_inheritable_attribute :cached_indices\n              indices[\"\#{attribute}\"] ||= []\n              indices[\"\#{attribute}\"] << value\n              write_inheritable_attribute :cached_indices, indices\n              Rails.cache.fetch attribute_cache_key(\"\#{attribute}\", value) do\n                self.find_by_\#{attribute}(value)\n              end\n            end\n          EOF\n        end\n      end\n\n      def with_method(*methods)\n        class_eval <<-EOF\n          after_update :expire_method_cache\n        EOF\n\n        write_inheritable_attribute :cached_methods, methods\n        methods.each do |meth|\n          class_eval <<-EOF\n            def cached_\#{meth}\n              Rails.cache.fetch method_cache_key(\"\#{meth}\") do\n                \#{meth}\n              end\n            end\n          EOF\n        end\n      end\n\n      def with_association(*association_names)\n        association_names.each do |association_name|\n          association = reflect_on_association(association_name)\n          if :belongs_to == association.macro\n            polymorphic = association.options[:polymorphic]\n            class_eval <<-EOF\n              def cached_\#{association_name}\n                Rails.cache.fetch belong_association_cache_key(\"\#{association_name}\", \#{polymorphic}) do\n                  \#{association_name}\n                end\n              end\n            EOF\n          else\n            reverse_association = association.klass.reflect_on_all_associations(:belongs_to).find { |reverse_association|\n              reverse_association.options[:polymorphic] ? reverse_association.name == association.options[:as] : reverse_association.klass == self\n            }\n            association.klass.class_eval <<-EOF\n              after_save :expire_\#{association_name}_cache\n              after_destroy :expire_\#{association_name}_cache\n\n              def expire_\#{association_name}_cache\n                if respond_to? :cached_\#{reverse_association.name}\n                  cached_\#{reverse_association.name}.expire_association_cache(:\#{association_name})\n                else\n                  \#{reverse_association.name}.expire_association_cache(:\#{association_name})\n                end\n              end\n            EOF\n\n            class_eval <<-EOF\n              def cached_\#{association_name}\n                Rails.cache.fetch have_association_cache_key(\"\#{association_name}\") do\n                  \#{association_name}\n                end\n              end\n            EOF\n          end\n        end\n      end\n\n      def attribute_cache_key(attribute, value)\n        \"\#{name.tableize}/attribute/\#{attribute}/\#{value}\"\n      end\n    end\n  end\nend\n"

Instance Method Details

#belong_association_cache_key(name, polymorphic = nil) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/cacheable.rb', line 146

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

#expire_association_cache(name) ⇒ Object



134
135
136
# File 'lib/cacheable.rb', line 134

def expire_association_cache(name)
  Rails.cache.delete have_association_cache_key(name)
end

#expire_attribute_cacheObject



116
117
118
119
120
121
122
123
124
# File 'lib/cacheable.rb', line 116

def expire_attribute_cache
  if indices = self.class.read_inheritable_attribute(:cached_indices)
    indices.each do |attribute, values|
      values.each do |value|
        Rails.cache.delete self.class.attribute_cache_key(attribute, value)
      end
    end
  end
end

#expire_key_cacheObject



112
113
114
# File 'lib/cacheable.rb', line 112

def expire_key_cache
  Rails.cache.delete model_cache_key
end

#expire_method_cacheObject



126
127
128
129
130
131
132
# File 'lib/cacheable.rb', line 126

def expire_method_cache
  if meths = self.class.read_inheritable_attribute(:cached_methods)
    meths.each do |meth|
      Rails.cache.delete method_cache_key(meth)
    end
  end
end

#expire_model_cacheObject



106
107
108
109
110
# File 'lib/cacheable.rb', line 106

def expire_model_cache
  expire_key_cache
  expire_attribute_cache
  expire_method_cache
end

#have_association_cache_key(name) ⇒ Object



154
155
156
# File 'lib/cacheable.rb', line 154

def have_association_cache_key(name)
  "#{model_cache_key}/association/#{name}"
end

#method_cache_key(meth) ⇒ Object



142
143
144
# File 'lib/cacheable.rb', line 142

def method_cache_key(meth)
  "#{model_cache_key}/method/#{meth}"
end

#model_cache_keyObject



138
139
140
# File 'lib/cacheable.rb', line 138

def model_cache_key
  "#{self.class.name.tableize}/#{self.id.to_i}"
end