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
|
# File 'lib/cacheable/types/association_cache.rb', line 4
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
define_method("cached_#{association_name}") do
Rails.cache.fetch belong_association_cache_key(association_name, polymorphic) do
send(association_name)
end
end
else
if through_reflection_name = association.options[:through]
through_association = self.reflect_on_association(through_reflection_name)
reverse_through_association = through_association.klass.reflect_on_all_associations(:belongs_to).first
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 do
after_commit "expire_#{association_name}_cache".to_sym
define_method("expire_#{association_name}_cache") do
if respond_to? "expire_#{reverse_association.name}_cache".to_sym
send("cached_#{reverse_association.name}").expire_association_cache(association_name)
else
send(reverse_association.name).send(reverse_through_association.name).expire_association_cache(association_name)
end
end
end
end
elsif :has_and_belongs_to_many == association.macro
reverse_association = association.klass.reflect_on_all_associations(:has_and_belongs_to_many).find { |reverse_association|
reverse_association.klass == self
}
association.klass.class_eval do
after_commit "expire_#{association_name}_cache".to_sym
define_method "expire_#{association_name}_cache" do
if respond_to? "cached_#{reverse_association.name}".to_sym
send("cached_#{reverse_association.name}").expire_association_cache(association_name)
else
send("#{reverse_association.name}").each do |assoc|
assoc.expire_association_cache(association_name)
end
end
end
end
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 do
after_commit "expire_#{association_name}_cache".to_sym
define_method "expire_#{association_name}_cache" do
if respond_to? "cached_#{reverse_association.name}".to_sym
send("cached_#{reverse_association.name}").expire_association_cache(association_name)
else
send("#{reverse_association.name}").expire_association_cache(association_name)
end
end
end
end
define_method("cached_#{association_name}") do
Rails.cache.fetch have_association_cache_key(association_name) do
send(association_name).respond_to?(:to_a) ? send(association_name).to_a : send(association_name)
end
end
end
end
end
|