simple_cacheable 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +0 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/ChangeLog +7 -0
- data/Gemfile +2 -4
- data/Gemfile.lock +115 -0
- data/README.md +1 -1
- data/lib/cacheable/caches.rb +15 -0
- data/lib/cacheable/expiry.rb +53 -0
- data/lib/cacheable/keys.rb +54 -0
- data/lib/cacheable/types/association_cache.rb +92 -0
- data/lib/cacheable/types/attribute_cache.rb +30 -0
- data/lib/cacheable/types/class_method_cache.rb +23 -0
- data/lib/cacheable/types/key_cache.rb +17 -0
- data/lib/cacheable/types/method_cache.rb +19 -0
- data/lib/cacheable/version.rb +1 -1
- data/lib/cacheable.rb +14 -263
- data/spec/cacheable/expiry_cache_spec.rb +81 -0
- data/spec/cacheable/types/association_cache_spec.rb +166 -0
- data/spec/cacheable/types/attribute_cache_spec.rb +60 -0
- data/spec/cacheable/types/class_method_cache_spec.rb +43 -0
- data/spec/cacheable/types/key_cache_spec.rb +28 -0
- data/spec/cacheable/types/method_cache_spec.rb +33 -0
- data/spec/cacheable_spec.rb +18 -292
- data/spec/models/post.rb +10 -1
- data/spec/spec_helper.rb +0 -1
- metadata +37 -22
- data/.rvmrc +0 -2
data/lib/cacheable.rb
CHANGED
@@ -1,273 +1,24 @@
|
|
1
1
|
require 'uri'
|
2
|
+
require "cacheable/caches"
|
3
|
+
require "cacheable/keys"
|
4
|
+
require "cacheable/expiry"
|
2
5
|
|
3
6
|
module Cacheable
|
4
7
|
def self.included(base)
|
5
|
-
base.
|
6
|
-
|
7
|
-
|
8
|
-
class_attribute :cached_key,
|
9
|
-
:cached_indices,
|
10
|
-
:cached_methods,
|
11
|
-
:cached_class_methods,
|
12
|
-
:cached_associations
|
13
|
-
instance_exec &block
|
14
|
-
end
|
15
|
-
|
16
|
-
def with_key
|
17
|
-
self.cached_key = true
|
18
|
-
|
19
|
-
class_eval <<-EOF
|
20
|
-
after_commit :expire_key_cache, :on => :update
|
21
|
-
|
22
|
-
def self.find_cached(id)
|
23
|
-
Rails.cache.fetch "#{name.tableize}/" + id.to_i.to_s do
|
24
|
-
self.find(id)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
EOF
|
28
|
-
end
|
29
|
-
|
30
|
-
def with_attribute(*attributes)
|
31
|
-
self.cached_indices = attributes.inject({}) { |indices, attribute| indices[attribute] = {} }
|
32
|
-
|
33
|
-
class_eval <<-EOF
|
34
|
-
after_commit :expire_attribute_cache, :on => :update
|
35
|
-
after_commit :expire_all_attribute_cache, :on => :update
|
36
|
-
EOF
|
37
|
-
|
38
|
-
attributes.each do |attribute|
|
39
|
-
class_eval <<-EOF
|
40
|
-
def self.find_cached_by_#{attribute}(value)
|
41
|
-
self.cached_indices["#{attribute}"] ||= []
|
42
|
-
self.cached_indices["#{attribute}"] << value
|
43
|
-
Rails.cache.fetch attribute_cache_key("#{attribute}", value) do
|
44
|
-
self.find_by_#{attribute}(value)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.find_cached_all_by_#{attribute}(value)
|
49
|
-
self.cached_indices["#{attribute}"] ||= []
|
50
|
-
self.cached_indices["#{attribute}"] << value
|
51
|
-
Rails.cache.fetch all_attribute_cache_key("#{attribute}", value) do
|
52
|
-
self.find_all_by_#{attribute}(value)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
EOF
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def with_method(*methods)
|
60
|
-
self.cached_methods = methods
|
61
|
-
|
62
|
-
class_eval <<-EOF
|
63
|
-
after_commit :expire_method_cache, :on => :update
|
64
|
-
EOF
|
65
|
-
|
66
|
-
methods.each do |meth|
|
67
|
-
class_eval <<-EOF
|
68
|
-
def cached_#{meth}
|
69
|
-
Rails.cache.fetch method_cache_key("#{meth}") do
|
70
|
-
#{meth}
|
71
|
-
end
|
72
|
-
end
|
73
|
-
EOF
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Cached class method
|
78
|
-
# Should expire on any instance save
|
79
|
-
def with_class_method(*methods)
|
80
|
-
self.cached_class_methods = methods
|
81
|
-
|
82
|
-
class_eval <<-EOF
|
83
|
-
after_commit :expire_class_method_cache, on: :update
|
84
|
-
EOF
|
85
|
-
|
86
|
-
methods.each do |meth|
|
87
|
-
class_eval <<-EOF
|
88
|
-
def self.cached_#{meth}
|
89
|
-
Rails.cache.fetch class_method_cache_key("#{meth}") do
|
90
|
-
#{meth}
|
91
|
-
end
|
92
|
-
end
|
93
|
-
EOF
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def with_association(*association_names)
|
99
|
-
self.cached_associations = association_names
|
100
|
-
|
101
|
-
association_names.each do |association_name|
|
102
|
-
association = reflect_on_association(association_name)
|
103
|
-
|
104
|
-
if :belongs_to == association.macro
|
105
|
-
polymorphic = association.options[:polymorphic]
|
106
|
-
polymorphic ||= false
|
107
|
-
class_eval <<-EOF
|
108
|
-
def cached_#{association_name}
|
109
|
-
Rails.cache.fetch belong_association_cache_key("#{association_name}", #{polymorphic}) do
|
110
|
-
#{association_name}
|
111
|
-
end
|
112
|
-
end
|
113
|
-
EOF
|
114
|
-
else
|
115
|
-
if through_reflection_name = association.options[:through]
|
116
|
-
through_association = self.reflect_on_association(through_reflection_name)
|
117
|
-
|
118
|
-
# FIXME it should be the only reflection but I'm not 100% positive
|
119
|
-
reverse_through_association = through_association.klass.reflect_on_all_associations(:belongs_to).first
|
120
|
-
|
121
|
-
# In a through association it doesn't have to be a belongs_to
|
122
|
-
reverse_association = association.klass.reflect_on_all_associations(:belongs_to).find { |reverse_association|
|
123
|
-
reverse_association.options[:polymorphic] ? reverse_association.name == association.source_reflection.options[:as] : reverse_association.klass == self
|
124
|
-
}
|
125
|
-
|
126
|
-
if reverse_association
|
127
|
-
association.klass.class_eval <<-EOF
|
128
|
-
after_commit :expire_#{association_name}_cache
|
129
|
-
|
130
|
-
def expire_#{association_name}_cache
|
131
|
-
if respond_to? :cached_#{reverse_association.name}
|
132
|
-
# cached_viewable.expire_association_cache
|
133
|
-
cached_#{reverse_association.name}.expire_association_cache(:#{association_name})
|
134
|
-
else
|
135
|
-
#{reverse_association.name}.#{reverse_through_association.name}.expire_association_cache(:#{association_name})
|
136
|
-
end
|
137
|
-
end
|
138
|
-
EOF
|
139
|
-
end
|
140
|
-
elsif :has_and_belongs_to_many == association.macro
|
141
|
-
# No such thing as a polymorphic has_and_belongs_to_many
|
142
|
-
reverse_association = association.klass.reflect_on_all_associations(:has_and_belongs_to_many).find { |reverse_association|
|
143
|
-
reverse_association.klass == self
|
144
|
-
}
|
145
|
-
|
146
|
-
association.klass.class_eval <<-EOF
|
147
|
-
after_commit :expire_#{association_name}_cache
|
148
|
-
|
149
|
-
def expire_#{association_name}_cache
|
150
|
-
if respond_to? :cached_#{reverse_association.name}
|
151
|
-
# cached_viewable.expire_association_cache
|
152
|
-
cached_#{reverse_association.name}.expire_association_cache(:#{association_name})
|
153
|
-
else
|
154
|
-
#{reverse_association.name}.each do |assoc|
|
155
|
-
assoc.expire_association_cache(:#{association_name})
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
EOF
|
160
|
-
else
|
161
|
-
reverse_association = association.klass.reflect_on_all_associations(:belongs_to).find { |reverse_association|
|
162
|
-
reverse_association.options[:polymorphic] ? reverse_association.name == association.options[:as] : reverse_association.klass == self
|
163
|
-
}
|
164
|
-
|
165
|
-
association.klass.class_eval <<-EOF
|
166
|
-
after_commit :expire_#{association_name}_cache
|
167
|
-
|
168
|
-
def expire_#{association_name}_cache
|
169
|
-
if respond_to? :cached_#{reverse_association.name}
|
170
|
-
cached_#{reverse_association.name}.expire_association_cache(:#{association_name})
|
171
|
-
else
|
172
|
-
#{reverse_association.name}.expire_association_cache(:#{association_name})
|
173
|
-
end
|
174
|
-
end
|
175
|
-
EOF
|
176
|
-
end
|
177
|
-
class_eval <<-EOF
|
178
|
-
def cached_#{association_name}
|
179
|
-
Rails.cache.fetch have_association_cache_key("#{association_name}") do
|
180
|
-
#{association_name}.respond_to?(:all) ? #{association_name}.all : #{association_name}
|
181
|
-
end
|
182
|
-
end
|
183
|
-
EOF
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def attribute_cache_key(attribute, value)
|
189
|
-
"#{name.tableize}/attribute/#{attribute}/#{URI.escape(value.to_s)}"
|
190
|
-
end
|
191
|
-
|
192
|
-
def all_attribute_cache_key(attribute, value)
|
193
|
-
"#{name.tableize}/attribute/#{attribute}/all/#{URI.escape(value.to_s)}"
|
194
|
-
end
|
195
|
-
|
196
|
-
def class_method_cache_key(meth)
|
197
|
-
"#{name.tableize}/class_method/#{meth}"
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
8
|
+
base.extend(Cacheable::Caches)
|
9
|
+
base.send :include, Cacheable::Keys
|
10
|
+
base.send :include, Cacheable::Expiry
|
201
11
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
expire_method_cache if self.class.cached_methods.present?
|
211
|
-
expire_class_method_cache if self.class.cached_class_methods.present?
|
212
|
-
|
213
|
-
if self.class.cached_associations.present?
|
214
|
-
self.class.cached_associations.each do |assoc|
|
215
|
-
expire_association_cache(assoc)
|
12
|
+
base.class_eval do
|
13
|
+
def self.model_cache(&block)
|
14
|
+
class_attribute :cached_key,
|
15
|
+
:cached_indices,
|
16
|
+
:cached_methods,
|
17
|
+
:cached_class_methods,
|
18
|
+
:cached_associations
|
19
|
+
instance_exec &block
|
216
20
|
end
|
217
21
|
end
|
218
22
|
end
|
219
23
|
|
220
|
-
def expire_key_cache
|
221
|
-
Rails.cache.delete model_cache_key
|
222
|
-
end
|
223
|
-
|
224
|
-
def expire_attribute_cache
|
225
|
-
self.class.cached_indices.each do |attribute, values|
|
226
|
-
value = self.send(attribute)
|
227
|
-
Rails.cache.delete self.class.attribute_cache_key(attribute, value)
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
def expire_all_attribute_cache
|
232
|
-
self.class.cached_indices.each do |attribute, values|
|
233
|
-
value = self.send(attribute)
|
234
|
-
Rails.cache.delete self.class.all_attribute_cache_key(attribute, value)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
def expire_method_cache
|
239
|
-
self.class.cached_methods.each do |meth|
|
240
|
-
Rails.cache.delete method_cache_key(meth)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
def expire_class_method_cache
|
245
|
-
self.class.cached_class_methods.each do |meth|
|
246
|
-
Rails.cache.delete self.class.class_method_cache_key(meth)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def expire_association_cache(name)
|
251
|
-
Rails.cache.delete have_association_cache_key(name)
|
252
|
-
end
|
253
|
-
|
254
|
-
def model_cache_key
|
255
|
-
"#{self.class.name.tableize}/#{self.id.to_i}"
|
256
|
-
end
|
257
|
-
|
258
|
-
def method_cache_key(meth)
|
259
|
-
"#{model_cache_key}/method/#{meth}"
|
260
|
-
end
|
261
|
-
|
262
|
-
def belong_association_cache_key(name, polymorphic=nil)
|
263
|
-
if polymorphic
|
264
|
-
"#{self.send("#{name}_type").tableize}/#{self.send("#{name}_id")}"
|
265
|
-
else
|
266
|
-
"#{name.tableize}/#{self.send(name + "_id")}"
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
def have_association_cache_key(name)
|
271
|
-
"#{model_cache_key}/association/#{name}"
|
272
|
-
end
|
273
24
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
let(:cache) { Rails.cache }
|
5
|
+
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@post1 = user.posts.create(:title => 'post1')
|
9
|
+
user2 = User.create(:login => 'PelegR')
|
10
|
+
user2.posts.create(:title => 'post3')
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
cache.clear
|
15
|
+
user.reload
|
16
|
+
end
|
17
|
+
|
18
|
+
context "expire_model_cache" do
|
19
|
+
it "should delete with_key cache" do
|
20
|
+
User.find_cached(user.id)
|
21
|
+
Rails.cache.read("users/#{user.id}").should_not be_nil
|
22
|
+
user.expire_model_cache
|
23
|
+
Rails.cache.read("users/#{user.id}").should be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should delete with_attribute cache" do
|
27
|
+
user = User.find_cached_by_login("flyerhzm")
|
28
|
+
Rails.cache.read("users/attribute/login/flyerhzm").should == user
|
29
|
+
user.expire_model_cache
|
30
|
+
Rails.cache.read("users/attribute/login/flyerhzm").should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should delete with_method cache" do
|
34
|
+
user.cached_last_post
|
35
|
+
Rails.cache.read("users/#{user.id}/method/last_post").should_not be_nil
|
36
|
+
user.expire_model_cache
|
37
|
+
Rails.cache.read("users/#{user.id}/method/last_post").should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should delete with_class_method cache (default_post)" do
|
41
|
+
Post.cached_default_post
|
42
|
+
Rails.cache.read("posts/class_method/default_post").should_not be_nil
|
43
|
+
@post1.expire_model_cache
|
44
|
+
Rails.cache.read("posts/class_method/default_post").should be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should delete with_class_method cache (retrieve_with_user_id)" do
|
48
|
+
Post.cached_retrieve_with_user_id(1)
|
49
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/1").should_not be_nil
|
50
|
+
@post1.expire_model_cache
|
51
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/1").should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should delete with_class_method cache (retrieve_with_user_id) with different arguments" do
|
55
|
+
Post.cached_retrieve_with_user_id(1)
|
56
|
+
Post.cached_retrieve_with_user_id(2)
|
57
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/1").should_not be_nil
|
58
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/2").should_not be_nil
|
59
|
+
@post1.expire_model_cache
|
60
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/1").should be_nil
|
61
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/2").should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should delete with_class_method cache (retrieve_with_both)" do
|
65
|
+
Post.cached_retrieve_with_both(1, 1)
|
66
|
+
Rails.cache.read("posts/class_method/retrieve_with_both/1+1").should_not be_nil
|
67
|
+
@post1.expire_model_cache
|
68
|
+
Rails.cache.read("posts/class_method/retrieve_with_both/1+1").should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: should we cache empty arrays?
|
72
|
+
it "should delete associations cache" do
|
73
|
+
user.cached_images
|
74
|
+
Rails.cache.read("users/#{user.id}/association/images").should_not be_nil
|
75
|
+
user.expire_model_cache
|
76
|
+
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
let(:cache) { Rails.cache }
|
5
|
+
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@post1 = user.posts.create(:title => 'post1')
|
9
|
+
@post2 = user.posts.create(:title => 'post2')
|
10
|
+
@image1 = @post1.images.create
|
11
|
+
@image2 = @post1.images.create
|
12
|
+
@comment1 = @post1.comments.create
|
13
|
+
@comment2 = @post1.comments.create
|
14
|
+
@tag1 = @post1.tags.create(title: "Rails")
|
15
|
+
@tag2 = @post1.tags.create(title: "Caching")
|
16
|
+
@group1 = Group.create(name: "Ruby On Rails")
|
17
|
+
@account = user.create_account(group: @group1)
|
18
|
+
end
|
19
|
+
|
20
|
+
before :each do
|
21
|
+
cache.clear
|
22
|
+
user.reload
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with_association" do
|
26
|
+
context "belongs_to" do
|
27
|
+
it "should not cache association" do
|
28
|
+
Rails.cache.read("users/#{user.id}").should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should cache Post#user" do
|
32
|
+
@post1.cached_user.should == user
|
33
|
+
Rails.cache.read("users/#{user.id}").should == user
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should cache Post#user multiple times" do
|
37
|
+
@post1.cached_user
|
38
|
+
@post1.cached_user.should == user
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should cache Comment#commentable with polymorphic" do
|
42
|
+
Rails.cache.read("posts/#{@post1.id}").should be_nil
|
43
|
+
@comment1.cached_commentable.should == @post1
|
44
|
+
Rails.cache.read("posts/#{@post1.id}").should == @post1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "has_many" do
|
49
|
+
it "should not cache associations" do
|
50
|
+
Rails.cache.read("users/#{user.id}/association/posts").should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should cache User#posts" do
|
54
|
+
user.cached_posts.should == [@post1, @post2]
|
55
|
+
Rails.cache.read("users/#{user.id}/association/posts").should == [@post1, @post2]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should cache User#posts multiple times" do
|
59
|
+
user.cached_posts
|
60
|
+
user.cached_posts.should == [@post1, @post2]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "has_many with polymorphic" do
|
65
|
+
it "should not cache associations" do
|
66
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should cache Post#comments" do
|
70
|
+
@post1.cached_comments.should == [@comment1, @comment2]
|
71
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should == [@comment1, @comment2]
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should cache Post#comments multiple times" do
|
75
|
+
@post1.cached_comments
|
76
|
+
@post1.cached_comments.should == [@comment1, @comment2]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "has_one" do
|
81
|
+
it "should not cache associations" do
|
82
|
+
Rails.cache.read("users/#{user.id}/association/account").should be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should cache User#posts" do
|
86
|
+
user.cached_account.should == @account
|
87
|
+
Rails.cache.read("users/#{user.id}/association/account").should == @account
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should cache User#posts multiple times" do
|
91
|
+
user.cached_account
|
92
|
+
user.cached_account.should == @account
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "has_many through" do
|
97
|
+
it "should not cache associations" do
|
98
|
+
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should cache User#images" do
|
102
|
+
user.cached_images.should == [@image1, @image2]
|
103
|
+
Rails.cache.read("users/#{user.id}/association/images").should == [@image1, @image2]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should cache User#images multiple times" do
|
107
|
+
user.cached_images
|
108
|
+
user.cached_images.should == [@image1, @image2]
|
109
|
+
end
|
110
|
+
|
111
|
+
context "expiry" do
|
112
|
+
it "should have the correct collection" do
|
113
|
+
@image3 = @post1.images.create
|
114
|
+
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
115
|
+
user.cached_images.should == [@image1, @image2, @image3]
|
116
|
+
Rails.cache.read("users/#{user.id}/association/images").should == [@image1, @image2, @image3]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "has_one through belongs_to" do
|
122
|
+
it "should not cache associations" do
|
123
|
+
Rails.cache.read("users/#{user.id}/association/group").should be_nil
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should cache User#group" do
|
127
|
+
user.cached_group.should == @group1
|
128
|
+
Rails.cache.read("users/#{user.id}/association/group").should == @group1
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should cache User#group multiple times" do
|
132
|
+
user.cached_group
|
133
|
+
user.cached_group.should == @group1
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
context "has_and_belongs_to_many" do
|
139
|
+
|
140
|
+
it "should not cache associations off the bat" do
|
141
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should be_nil
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should cache Post#tags" do
|
145
|
+
@post1.cached_tags.should == [@tag1, @tag2]
|
146
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [@tag1, @tag2]
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should handle multiple requests" do
|
150
|
+
@post1.cached_tags
|
151
|
+
@post1.cached_tags.should == [@tag1, @tag2]
|
152
|
+
end
|
153
|
+
|
154
|
+
context "expiry" do
|
155
|
+
it "should have the correct collection" do
|
156
|
+
@tag3 = @post1.tags.create!(title: "Invalidation is hard")
|
157
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should be_nil
|
158
|
+
@post1.cached_tags.should == [@tag1, @tag2, @tag3]
|
159
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [@tag1, @tag2, @tag3]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
let(:cache) { Rails.cache }
|
5
|
+
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@post1 = user.posts.create(:title => 'post1')
|
9
|
+
@post2 = user.posts.create(:title => 'post2')
|
10
|
+
end
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
cache.clear
|
14
|
+
user.reload
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with_attribute" do
|
18
|
+
it "should not cache User.find_by_login" do
|
19
|
+
Rails.cache.read("users/attribute/login/flyerhzm").should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should cache by User.find_by_login" do
|
23
|
+
User.find_cached_by_login("flyerhzm").should == user
|
24
|
+
Rails.cache.read("users/attribute/login/flyerhzm").should == user
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should get cached by User.find_by_login multiple times" do
|
28
|
+
User.find_cached_by_login("flyerhzm")
|
29
|
+
User.find_cached_by_login("flyerhzm").should == user
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should escape whitespace" do
|
33
|
+
new_user = User.create(:login => "user space")
|
34
|
+
User.find_cached_by_login("user space").should == new_user
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should handle fixed numbers" do
|
38
|
+
Post.find_cached_by_user_id(user.id).should == @post1
|
39
|
+
Rails.cache.read("posts/attribute/user_id/#{user.id}").should == @post1
|
40
|
+
end
|
41
|
+
|
42
|
+
context "find_all" do
|
43
|
+
it "should not cache Post.find_all_by_user_id" do
|
44
|
+
Rails.cache.read("posts/attribute/user_id/all/#{user.id}").should be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should cache by Post.find_cached_all_by_user_id" do
|
48
|
+
Post.find_cached_all_by_user_id(user.id).should == [@post1, @post2]
|
49
|
+
Rails.cache.read("posts/attribute/user_id/all/#{user.id}").should == [@post1, @post2]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should get cached by Post.find_cached_all_by_user_id multiple times" do
|
53
|
+
Post.find_cached_all_by_user_id(user.id)
|
54
|
+
Post.find_cached_all_by_user_id(user.id).should == [@post1, @post2]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
let(:cache) { Rails.cache }
|
5
|
+
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@post1 = user.posts.create(:title => 'post1')
|
9
|
+
@post2 = user.posts.create(:title => 'post2')
|
10
|
+
end
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
cache.clear
|
14
|
+
user.reload
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with_class_method" do
|
18
|
+
it "should not cache Post.default_post" do
|
19
|
+
Rails.cache.read("posts/class_method/default_post").should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should cache Post.default_post" do
|
23
|
+
Post.cached_default_post.should == @post1
|
24
|
+
Rails.cache.read("posts/class_method/default_post").should == @post1
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should cache Post.default_post multiple times" do
|
28
|
+
Post.cached_default_post
|
29
|
+
Post.cached_default_post.should == @post1
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should cache Post.retrieve_with_user_id" do
|
33
|
+
Post.cached_retrieve_with_user_id(1).should == @post1
|
34
|
+
Rails.cache.read("posts/class_method/retrieve_with_user_id/1").should == @post1
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should cache Post.retrieve_with_both with multiple arguments" do
|
38
|
+
Post.cached_retrieve_with_both(1, 1).should be_true
|
39
|
+
Rails.cache.read("posts/class_method/retrieve_with_both/1+1").should be_true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
let(:cache) { Rails.cache }
|
5
|
+
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
cache.clear
|
9
|
+
user.reload
|
10
|
+
end
|
11
|
+
|
12
|
+
context "with_key" do
|
13
|
+
it "should not cache key" do
|
14
|
+
Rails.cache.read("users/#{user.id}").should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should cache by User#id" do
|
18
|
+
User.find_cached(user.id).should == user
|
19
|
+
Rails.cache.read("users/#{user.id}").should == user
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should get cached by User#id multiple times" do
|
23
|
+
User.find_cached(user.id)
|
24
|
+
User.find_cached(user.id).should == user
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|