simple_cacheable 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|