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"
|