simple_cacheable 1.4.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/Appraisals +7 -0
- data/ChangeLog +9 -0
- data/Gemfile +10 -9
- data/Gemfile.lock +44 -46
- data/README.md +10 -0
- data/Rakefile +2 -0
- data/cacheable.gemspec +4 -2
- data/gemfiles/3.2.gemfile +10 -0
- data/gemfiles/3.2.gemfile.lock +117 -0
- data/gemfiles/4.0.gemfile +10 -0
- data/gemfiles/4.0.gemfile.lock +112 -0
- data/lib/cacheable.rb +11 -0
- data/lib/cacheable/expiry.rb +3 -1
- data/lib/cacheable/keys.rb +29 -7
- data/lib/cacheable/model_fetch.rb +59 -0
- data/lib/cacheable/types/association_cache.rb +128 -73
- data/lib/cacheable/types/attribute_cache.rb +7 -3
- data/lib/cacheable/types/class_method_cache.rb +2 -2
- data/lib/cacheable/types/key_cache.rb +2 -1
- data/lib/cacheable/types/method_cache.rb +10 -3
- data/lib/cacheable/version.rb +1 -1
- data/spec/cacheable/expiry_cache_spec.rb +44 -45
- data/spec/cacheable/model_fetch_spec.rb +86 -0
- data/spec/cacheable/types/association_cache_spec.rb +267 -43
- data/spec/cacheable/types/attribute_cache_spec.rb +31 -24
- data/spec/cacheable/types/class_method_cache_spec.rb +49 -21
- data/spec/cacheable/types/key_cache_spec.rb +51 -12
- data/spec/cacheable/types/method_cache_spec.rb +76 -37
- data/spec/cacheable_spec.rb +19 -20
- data/spec/models/account.rb +8 -0
- data/spec/models/post.rb +21 -1
- data/spec/models/user.rb +38 -2
- data/spec/spec_helper.rb +13 -0
- data/spec/support/ar_patches.rb +51 -0
- data/spec/support/coder_macro.rb +12 -0
- metadata +34 -7
@@ -9,10 +9,17 @@ module Cacheable
|
|
9
9
|
end
|
10
10
|
|
11
11
|
methods.each do |meth|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
method_name = "cached_#{meth}"
|
13
|
+
define_method(method_name) do
|
14
|
+
iv = Cacheable.escape_punctuation("@#{method_name}")
|
15
|
+
if instance_variable_get(iv).nil?
|
16
|
+
instance_variable_set(iv,
|
17
|
+
(Cacheable.fetch method_cache_key(meth) do
|
18
|
+
send(meth)
|
19
|
+
end)
|
20
|
+
)
|
15
21
|
end
|
22
|
+
instance_variable_get(iv)
|
16
23
|
end
|
17
24
|
end
|
18
25
|
end
|
data/lib/cacheable/version.rb
CHANGED
@@ -2,41 +2,40 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Cacheable do
|
4
4
|
let(:cache) { Rails.cache }
|
5
|
-
let(:user) { User.create(:login => 'flyerhzm') }
|
6
|
-
let(:descendant) { Descendant.create(:login => "scotterc")}
|
7
5
|
|
8
6
|
before :all do
|
9
|
-
@
|
10
|
-
|
7
|
+
@user = User.create(:login => 'flyerhzm')
|
8
|
+
@descendant = Descendant.create(:login => "scotterc")
|
9
|
+
@post1 = @user.posts.create(:title => 'post1')
|
10
|
+
user2 = User.create(:login => 'PelegR')
|
11
11
|
user2.posts.create(:title => 'post3')
|
12
|
-
@post3
|
12
|
+
@post3 = @descendant.posts.create(:title => 'post3')
|
13
13
|
end
|
14
14
|
|
15
15
|
before :each do
|
16
|
-
|
17
|
-
user.reload
|
16
|
+
@user.reload
|
18
17
|
end
|
19
18
|
|
20
19
|
context "expire_model_cache" do
|
21
20
|
it "should delete with_key cache" do
|
22
|
-
User.find_cached(user.id)
|
23
|
-
Rails.cache.read("users/#{user.id}").should_not be_nil
|
24
|
-
user.expire_model_cache
|
25
|
-
Rails.cache.read("users/#{user.id}").should be_nil
|
21
|
+
User.find_cached(@user.id)
|
22
|
+
Rails.cache.read("users/#{@user.id}").should_not be_nil
|
23
|
+
@user.expire_model_cache
|
24
|
+
Rails.cache.read("users/#{@user.id}").should be_nil
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should delete with_attribute cache" do
|
29
|
-
user = User.find_cached_by_login("flyerhzm")
|
30
|
-
Rails.cache.read("users/attribute/login/flyerhzm").should == user
|
31
|
-
user.expire_model_cache
|
28
|
+
@user = User.find_cached_by_login("flyerhzm")
|
29
|
+
Rails.cache.read("users/attribute/login/flyerhzm").should == {:class => @user.class, 'attributes' => @user.attributes}
|
30
|
+
@user.expire_model_cache
|
32
31
|
Rails.cache.read("users/attribute/login/flyerhzm").should be_nil
|
33
32
|
end
|
34
33
|
|
35
34
|
it "should delete with_method cache" do
|
36
|
-
user.cached_last_post
|
37
|
-
Rails.cache.read("users/#{user.id}/method/last_post").should_not be_nil
|
38
|
-
user.expire_model_cache
|
39
|
-
Rails.cache.read("users/#{user.id}/method/last_post").should be_nil
|
35
|
+
@user.cached_last_post
|
36
|
+
Rails.cache.read("users/#{@user.id}/method/last_post").should_not be_nil
|
37
|
+
@user.expire_model_cache
|
38
|
+
Rails.cache.read("users/#{@user.id}/method/last_post").should be_nil
|
40
39
|
end
|
41
40
|
|
42
41
|
it "should delete with_class_method cache (default_post)" do
|
@@ -71,10 +70,10 @@ describe Cacheable do
|
|
71
70
|
end
|
72
71
|
|
73
72
|
it "should delete associations cache" do
|
74
|
-
user.cached_images
|
75
|
-
Rails.cache.read("users/#{user.id}/association/images").should_not be_nil
|
76
|
-
user.expire_model_cache
|
77
|
-
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
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
|
78
77
|
end
|
79
78
|
|
80
79
|
end
|
@@ -92,7 +91,7 @@ describe Cacheable do
|
|
92
91
|
|
93
92
|
it "should have cached_methods" do
|
94
93
|
User.cached_methods.should_not be_nil
|
95
|
-
User.cached_methods.should == [:last_post]
|
94
|
+
User.cached_methods.should == [:last_post, :bad_iv_name!, :bad_iv_name?, :admin?, :hash_with_class_key]
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|
@@ -101,7 +100,7 @@ describe Cacheable do
|
|
101
100
|
Rails.cache.read("users/class_method/default_name").should be_nil
|
102
101
|
User.cached_default_name
|
103
102
|
Rails.cache.read("users/class_method/default_name").should == "flyerhzm"
|
104
|
-
user.expire_model_cache
|
103
|
+
@user.expire_model_cache
|
105
104
|
Rails.cache.read("users/class_method/default_name").should be_nil
|
106
105
|
end
|
107
106
|
end
|
@@ -119,49 +118,49 @@ describe Cacheable do
|
|
119
118
|
|
120
119
|
it "should have cached_methods" do
|
121
120
|
Descendant.cached_methods.should_not be_nil
|
122
|
-
Descendant.cached_methods.should == [:last_post, :name]
|
121
|
+
Descendant.cached_methods.should == [:last_post, :bad_iv_name!, :bad_iv_name?, :admin?, :hash_with_class_key, :name]
|
123
122
|
end
|
124
123
|
|
125
124
|
context "expiring method cache" do
|
126
125
|
it "expires correctly from inherited attributes" do
|
127
|
-
Rails.cache.read("
|
128
|
-
descendant.cached_last_post.should == descendant.last_post
|
129
|
-
Rails.cache.read("
|
130
|
-
|
131
|
-
|
126
|
+
Rails.cache.read("users/#{@descendant.id}/method/last_post").should be_nil
|
127
|
+
@descendant.cached_last_post.should == @descendant.last_post
|
128
|
+
Rails.cache.read("users/#{@descendant.id}/method/last_post").should == {:class => @descendant.last_post.class,
|
129
|
+
'attributes' => @descendant.last_post.attributes}
|
130
|
+
@descendant.expire_model_cache
|
131
|
+
Rails.cache.read("users/#{@descendant.id}/method/last_post").should be_nil
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
context "expiring attribute cache" do
|
136
136
|
it "expires correctly from inherited attributes" do
|
137
|
-
Rails.cache.read("
|
138
|
-
Descendant.find_cached_by_login("scotterc").should == descendant
|
139
|
-
Rails.cache.read("
|
140
|
-
descendant.expire_model_cache
|
141
|
-
Rails.cache.read("
|
137
|
+
Rails.cache.read("users/attribute/login/scotterc").should be_nil
|
138
|
+
Descendant.find_cached_by_login("scotterc").should == @descendant
|
139
|
+
Rails.cache.read("users/attribute/login/scotterc").should == {:class => @descendant.class, 'attributes' => @descendant.attributes}
|
140
|
+
@descendant.expire_model_cache
|
141
|
+
Rails.cache.read("users/attribute/login/scotterc").should be_nil
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
145
|
context "expiring association cache" do
|
146
146
|
it "expires correctly from inherited attributes" do
|
147
|
-
Rails.cache.read("
|
148
|
-
descendant.cached_posts.should == [@post3]
|
149
|
-
Rails.cache.read("
|
150
|
-
descendant.expire_model_cache
|
151
|
-
Rails.cache.read("
|
147
|
+
Rails.cache.read("users/#{@descendant.id}/association/posts").should be_nil
|
148
|
+
@descendant.cached_posts.should == [@post3]
|
149
|
+
Rails.cache.read("users/#{@descendant.id}/association/posts").should == [coder(@post3)]
|
150
|
+
@descendant.expire_model_cache
|
151
|
+
Rails.cache.read("users/#{@descendant.id}/association/posts").should be_nil
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
context "expiring class_method cache" do
|
156
156
|
it "expires correctly from inherited attributes" do
|
157
|
-
Rails.cache.read("
|
157
|
+
Rails.cache.read("users/class_method/default_name").should be_nil
|
158
158
|
Descendant.cached_default_name
|
159
|
-
Rails.cache.read("
|
160
|
-
descendant.expire_model_cache
|
161
|
-
Rails.cache.read("
|
159
|
+
Rails.cache.read("users/class_method/default_name").should == "ScotterC"
|
160
|
+
@descendant.expire_model_cache
|
161
|
+
Rails.cache.read("users/class_method/default_name").should be_nil
|
162
162
|
end
|
163
163
|
end
|
164
164
|
end
|
165
165
|
end
|
166
|
-
|
167
166
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cacheable do
|
4
|
+
|
5
|
+
let(:cache) { Rails.cache }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@user = User.create(:login => 'flyerhzm')
|
9
|
+
@post1 = @user.posts.create(:title => 'post1')
|
10
|
+
@post2 = @user.posts.create(:title => 'post2')
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "singleton fetch" do
|
14
|
+
it "should find an object by id" do
|
15
|
+
key = User.instance_cache_key(1)
|
16
|
+
Cacheable.fetch(key) do
|
17
|
+
User.find(1)
|
18
|
+
end.should == @user
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "association fetch" do
|
23
|
+
it "should find associations by name" do
|
24
|
+
key = @user.have_association_cache_key(:posts)
|
25
|
+
Cacheable.fetch(key) do
|
26
|
+
@user.send(:posts)
|
27
|
+
end.should == [@post1, @post2]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "unit tests" do
|
32
|
+
describe "#write" do
|
33
|
+
it "should write an encoded object to the cache" do
|
34
|
+
Rails.cache.read(@user.model_cache_key).should be_nil
|
35
|
+
Cacheable.send(:write, @user.model_cache_key, @user)
|
36
|
+
Rails.cache.read(@user.model_cache_key).should == { :class => @user.class, 'attributes' => @user.attributes }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#read" do
|
41
|
+
it "should decode an encoded object read from the cache" do
|
42
|
+
Rails.cache.read(@user.model_cache_key).should be_nil
|
43
|
+
Rails.cache.write(@user.model_cache_key, {:class => @user.class, 'attributes' => @user.attributes} )
|
44
|
+
Cacheable.send(:read, @user.model_cache_key).should == @user
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns nil if value is nil" do
|
48
|
+
Cacheable.send(:read, "clearly_a_nil_key").should be_nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#coder_from_record" do
|
53
|
+
it "should encode an object" do
|
54
|
+
Cacheable.send(:coder_from_record, @user).should == {:class => @user.class, 'attributes' => @user.attributes}
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns nil if record is nil" do
|
58
|
+
Cacheable.send(:coder_from_record, nil).should be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns the record if it's not an AR object" do
|
62
|
+
Cacheable.send(:coder_from_record, false).should be_false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#record_from_coder" do
|
67
|
+
it "should decode an object" do
|
68
|
+
Cacheable.send(:record_from_coder, {:class => @user.class,
|
69
|
+
'attributes' => @user.attributes}).should == @user
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns the object if it's not a hash" do
|
73
|
+
Cacheable.send(:record_from_coder, false).should be_false
|
74
|
+
Cacheable.send(:record_from_coder, @user).should == @user
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "returning a hash with class key" do
|
80
|
+
it "handles a hash with a class key" do
|
81
|
+
hash_value = {:foo => "Bar", :class => "batman"}
|
82
|
+
@user.cached_hash_with_class_key.should == hash_value
|
83
|
+
@user.cached_hash_with_class_key.should == hash_value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -2,63 +2,106 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Cacheable do
|
4
4
|
let(:cache) { Rails.cache }
|
5
|
-
let(:user) { User.create(:login => 'flyerhzm') }
|
6
5
|
|
7
6
|
before :all do
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
7
|
+
@user = User.create(:login => 'flyerhzm')
|
8
|
+
@user2 = User.create(:login => 'ScotterC')
|
9
|
+
@post1 = @user.posts.create(:title => 'post1')
|
10
|
+
@post2 = @user.posts.create(:title => 'post2')
|
11
|
+
@post3 = Post.create
|
12
|
+
@image1 = @post1.images.create
|
13
|
+
@image2 = @post1.images.create
|
12
14
|
@comment1 = @post1.comments.create
|
13
15
|
@comment2 = @post1.comments.create
|
14
|
-
@tag1
|
15
|
-
@tag2
|
16
|
-
@group1
|
17
|
-
@account
|
16
|
+
@tag1 = @post1.tags.create(title: "Rails")
|
17
|
+
@tag2 = @post1.tags.create(title: "Caching")
|
18
|
+
@group1 = Group.create(name: "Ruby On Rails")
|
19
|
+
@account = @user.create_account(group: @group1)
|
18
20
|
@location = @post1.create_location(city: "New York")
|
21
|
+
@account_location = @account.create_account_location(city: "New Orleans")
|
22
|
+
@account.save # @account doesn't persist location id?
|
19
23
|
end
|
20
24
|
|
21
25
|
before :each do
|
22
|
-
|
23
|
-
|
26
|
+
@user.reload
|
27
|
+
@post1.reload
|
24
28
|
end
|
25
29
|
|
26
30
|
context "with_association" do
|
31
|
+
before :each do
|
32
|
+
@post1.instance_variable_set("@cached_user", nil)
|
33
|
+
@comment1.instance_variable_set("@cached_commentable", nil)
|
34
|
+
end
|
35
|
+
|
27
36
|
context "belongs_to" do
|
28
37
|
it "should not cache association" do
|
29
|
-
Rails.cache.read("users/#{user.id}").should be_nil
|
38
|
+
Rails.cache.read("users/#{@user.id}").should be_nil
|
30
39
|
end
|
31
40
|
|
32
41
|
it "should cache Post#user" do
|
33
|
-
@post1.cached_user.should == user
|
34
|
-
Rails.cache.read("users/#{user.id}").should == user
|
42
|
+
@post1.cached_user.should == @user
|
43
|
+
Rails.cache.read("users/#{@user.id}").should == coder(@user)
|
35
44
|
end
|
36
45
|
|
37
46
|
it "should cache Post#user multiple times" do
|
38
47
|
@post1.cached_user
|
39
|
-
@post1.cached_user.should == user
|
48
|
+
@post1.cached_user.should == @user
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not expire cached user on save" do
|
52
|
+
Rails.cache.read("users/#{@user.id}").should be_nil
|
53
|
+
@post1.cached_user.should == @user
|
54
|
+
Rails.cache.read("users/#{@user.id}").should == coder(@user)
|
55
|
+
@post1.save
|
56
|
+
Rails.cache.read("users/#{@user.id}").should == coder(@user)
|
40
57
|
end
|
41
58
|
|
42
59
|
it "should cache Comment#commentable with polymorphic" do
|
43
60
|
Rails.cache.read("posts/#{@post1.id}").should be_nil
|
44
61
|
@comment1.cached_commentable.should == @post1
|
45
|
-
Rails.cache.read("posts/#{@post1.id}").should == @post1
|
62
|
+
Rails.cache.read("posts/#{@post1.id}").should == coder(@post1)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return nil if there are none" do
|
66
|
+
@post3.cached_user.should be_nil
|
46
67
|
end
|
47
68
|
end
|
48
69
|
|
49
70
|
context "has_many" do
|
50
71
|
it "should not cache associations" do
|
51
|
-
Rails.cache.read("users/#{user.id}/association/posts").should be_nil
|
72
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should be_nil
|
52
73
|
end
|
53
74
|
|
54
75
|
it "should cache User#posts" do
|
55
|
-
user.cached_posts.should == [@post1, @post2]
|
56
|
-
Rails.cache.read("users/#{user.id}/association/posts").should == [@post1, @post2]
|
76
|
+
@user.cached_posts.should == [@post1, @post2]
|
77
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should == [coder(@post1), coder(@post2)]
|
57
78
|
end
|
58
79
|
|
59
80
|
it "should cache User#posts multiple times" do
|
60
|
-
user.cached_posts
|
61
|
-
user.cached_posts.should == [@post1, @post2]
|
81
|
+
@user.cached_posts
|
82
|
+
@user.cached_posts.should == [@post1, @post2]
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should expire associations on save of associated objects" do
|
86
|
+
pending #heisenbug. When inspected it works fine
|
87
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should be_nil
|
88
|
+
@user.cached_posts.should == [@post1, @post2]
|
89
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should_not be_nil
|
90
|
+
@post1.save
|
91
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should be_nil
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should expire associations on save of parent" do
|
95
|
+
pending #heisenbug. When inspected it works fine
|
96
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should be_nil
|
97
|
+
@user.cached_posts.should == [@post1, @post2]
|
98
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should_not be_nil
|
99
|
+
@user.save
|
100
|
+
Rails.cache.read("users/#{@user.id}/association/posts").should be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return empty if there are none" do
|
104
|
+
@user2.cached_posts.should == []
|
62
105
|
end
|
63
106
|
end
|
64
107
|
|
@@ -69,69 +112,127 @@ describe Cacheable do
|
|
69
112
|
|
70
113
|
it "should cache Post#comments" do
|
71
114
|
@post1.cached_comments.should == [@comment1, @comment2]
|
72
|
-
Rails.cache.read("posts/#{@post1.id}/association/comments").should == [@comment1, @comment2]
|
115
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should == [coder(@comment1), coder(@comment2)]
|
73
116
|
end
|
74
117
|
|
75
118
|
it "should cache Post#comments multiple times" do
|
76
119
|
@post1.cached_comments
|
77
120
|
@post1.cached_comments.should == [@comment1, @comment2]
|
78
121
|
end
|
122
|
+
|
123
|
+
it "should expire associations on save" do
|
124
|
+
pending
|
125
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should be_nil
|
126
|
+
@post1.cached_comments.should == [@comment1, @comment2]
|
127
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should == [coder(@comment1), coder(@comment2)]
|
128
|
+
@post1.save
|
129
|
+
Rails.cache.read("posts/#{@post1.id}/association/comments").should be_nil
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return empty if there are none" do
|
133
|
+
@post3.cached_comments.should == []
|
134
|
+
end
|
79
135
|
end
|
80
136
|
|
81
137
|
context "has_one" do
|
82
138
|
it "should not cache associations" do
|
83
|
-
Rails.cache.read("users/#{user.id}/association/account").should be_nil
|
139
|
+
Rails.cache.read("users/#{@user.id}/association/account").should be_nil
|
84
140
|
end
|
85
141
|
|
86
142
|
it "should cache User#posts" do
|
87
|
-
user.cached_account.should == @account
|
88
|
-
Rails.cache.read("users/#{user.id}/association/account").should == @account
|
143
|
+
@user.cached_account.should == @account
|
144
|
+
Rails.cache.read("users/#{@user.id}/association/account").should == coder(@account)
|
89
145
|
end
|
90
146
|
|
91
147
|
it "should cache User#posts multiple times" do
|
92
|
-
user.cached_account
|
93
|
-
user.cached_account.should == @account
|
148
|
+
@user.cached_account
|
149
|
+
@user.cached_account.should == @account
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should expire association on save" do
|
153
|
+
pending
|
154
|
+
Rails.cache.read("users/#{@user.id}/association/account").should be_nil
|
155
|
+
@user.cached_account.should == @account
|
156
|
+
Rails.cache.read("users/#{@user.id}/association/account").should == coder(@account)
|
157
|
+
@user.save
|
158
|
+
Rails.cache.read("users/#{@user.id}/association/account").should be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should return nil if there are none" do
|
162
|
+
@user2.cached_account.should be_nil
|
94
163
|
end
|
95
164
|
end
|
96
165
|
|
97
166
|
context "has_many through" do
|
98
167
|
it "should not cache associations" do
|
99
|
-
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
168
|
+
Rails.cache.read("users/#{@user.id}/association/images").should be_nil
|
100
169
|
end
|
101
170
|
|
102
171
|
it "should cache User#images" do
|
103
|
-
user.cached_images.should == [@image1, @image2]
|
104
|
-
Rails.cache.read("users/#{user.id}/association/images").should == [@image1, @image2]
|
172
|
+
@user.cached_images.should == [@image1, @image2]
|
173
|
+
Rails.cache.read("users/#{@user.id}/association/images").should == [coder(@image1), coder(@image2)]
|
105
174
|
end
|
106
175
|
|
107
176
|
it "should cache User#images multiple times" do
|
108
|
-
user.cached_images
|
109
|
-
user.cached_images.should == [@image1, @image2]
|
177
|
+
@user.cached_images
|
178
|
+
@user.cached_images.should == [@image1, @image2]
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should expire associations on save" do
|
182
|
+
pending
|
183
|
+
Rails.cache.read("users/#{@user.id}/association/images").should be_nil
|
184
|
+
@user.cached_images.should == [@image1, @image2]
|
185
|
+
Rails.cache.read("users/#{@user.id}/association/images").should == [coder(@image1), coder(@image2)]
|
186
|
+
@user.save
|
187
|
+
Rails.cache.read("users/#{@user.id}/association/images").should be_nil
|
110
188
|
end
|
111
189
|
|
112
190
|
context "expiry" do
|
191
|
+
before :each do
|
192
|
+
@user.instance_variable_set("@cached_images", nil)
|
193
|
+
end
|
194
|
+
|
113
195
|
it "should have the correct collection" do
|
114
196
|
@image3 = @post1.images.create
|
115
|
-
Rails.cache.read("users/#{user.id}/association/images").should be_nil
|
116
|
-
user.cached_images.should == [@image1, @image2, @image3]
|
117
|
-
Rails.cache.read("users/#{user.id}/association/images").should == [@image1,
|
197
|
+
Rails.cache.read("users/#{@user.id}/association/images").should be_nil
|
198
|
+
@user.cached_images.should == [@image1, @image2, @image3]
|
199
|
+
Rails.cache.read("users/#{@user.id}/association/images").should == [coder(@image1),
|
200
|
+
coder(@image2),
|
201
|
+
coder(@image3)]
|
118
202
|
end
|
119
203
|
end
|
204
|
+
|
205
|
+
it "should return empty if there are none" do
|
206
|
+
@user2.cached_images.should == []
|
207
|
+
end
|
120
208
|
end
|
121
209
|
|
122
210
|
context "has_one through belongs_to" do
|
123
211
|
it "should not cache associations" do
|
124
|
-
Rails.cache.read("users/#{user.id}/association/group").should be_nil
|
212
|
+
Rails.cache.read("users/#{@user.id}/association/group").should be_nil
|
125
213
|
end
|
126
214
|
|
127
215
|
it "should cache User#group" do
|
128
|
-
user.cached_group.should == @group1
|
129
|
-
Rails.cache.read("users/#{user.id}/association/group").should == @group1
|
216
|
+
@user.cached_group.should == @group1
|
217
|
+
Rails.cache.read("users/#{@user.id}/association/group").should == coder(@group1)
|
130
218
|
end
|
131
219
|
|
132
220
|
it "should cache User#group multiple times" do
|
133
|
-
user.cached_group
|
134
|
-
user.cached_group.should == @group1
|
221
|
+
@user.cached_group
|
222
|
+
@user.cached_group.should == @group1
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should expire association on save" do
|
226
|
+
pending
|
227
|
+
Rails.cache.read("users/#{@user.id}/association/group").should be_nil
|
228
|
+
@user.cached_group.should == @group1
|
229
|
+
Rails.cache.read("users/#{@user.id}/association/group").should == coder(@group1)
|
230
|
+
@user.save
|
231
|
+
Rails.cache.read("users/#{@user.id}/association/group").should be_nil
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should return nil if there are none" do
|
235
|
+
@user2.cached_group.should be_nil
|
135
236
|
end
|
136
237
|
|
137
238
|
end
|
@@ -144,7 +245,7 @@ describe Cacheable do
|
|
144
245
|
|
145
246
|
it "should cache Post#tags" do
|
146
247
|
@post1.cached_tags.should == [@tag1, @tag2]
|
147
|
-
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [@tag1, @tag2]
|
248
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [coder(@tag1), coder(@tag2)]
|
148
249
|
end
|
149
250
|
|
150
251
|
it "should handle multiple requests" do
|
@@ -152,12 +253,31 @@ describe Cacheable do
|
|
152
253
|
@post1.cached_tags.should == [@tag1, @tag2]
|
153
254
|
end
|
154
255
|
|
256
|
+
it "should expire association on save" do
|
257
|
+
pending
|
258
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should be_nil
|
259
|
+
@post1.cached_tags.should == [@tag1, @tag2]
|
260
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [coder(@tag1), coder(@tag2)]
|
261
|
+
@post1.save
|
262
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should be_nil
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should return empty if there are none" do
|
266
|
+
@post3.cached_tags.should == []
|
267
|
+
end
|
268
|
+
|
155
269
|
context "expiry" do
|
270
|
+
before :each do
|
271
|
+
@post1.instance_variable_set("@cached_tags", nil)
|
272
|
+
end
|
273
|
+
|
156
274
|
it "should have the correct collection" do
|
157
275
|
@tag3 = @post1.tags.create!(title: "Invalidation is hard")
|
158
276
|
Rails.cache.read("posts/#{@post1.id}/association/tags").should be_nil
|
159
277
|
@post1.cached_tags.should == [@tag1, @tag2, @tag3]
|
160
|
-
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [@tag1,
|
278
|
+
Rails.cache.read("posts/#{@post1.id}/association/tags").should == [coder(@tag1),
|
279
|
+
coder(@tag2),
|
280
|
+
coder(@tag3)]
|
161
281
|
end
|
162
282
|
end
|
163
283
|
end
|
@@ -187,7 +307,7 @@ describe Cacheable do
|
|
187
307
|
|
188
308
|
it "shouldn't hit location" do
|
189
309
|
@location.expects(:expire_association_cache).with(:images).never
|
190
|
-
user.save
|
310
|
+
@user.save
|
191
311
|
end
|
192
312
|
|
193
313
|
context "with a user" do
|
@@ -214,4 +334,108 @@ describe Cacheable do
|
|
214
334
|
|
215
335
|
end
|
216
336
|
|
337
|
+
# https://github.com/Shopify/identity_cache/pull/55/files
|
338
|
+
describe "rails association cache" do
|
339
|
+
it "should not load associated records" do
|
340
|
+
@user.posts
|
341
|
+
cached_user = User.find_cached(@user.id)
|
342
|
+
cached_user.posts.loaded?.should be_false
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
describe "memoization" do
|
347
|
+
describe "belongs to" do
|
348
|
+
before :each do
|
349
|
+
@post1.instance_variable_set("@cached_user", nil)
|
350
|
+
@post1.expire_model_cache
|
351
|
+
end
|
352
|
+
|
353
|
+
it "memoizes cache calls" do
|
354
|
+
@post1.instance_variable_get("@cached_user").should be_nil
|
355
|
+
@post1.cached_user.should == @post1.user
|
356
|
+
@post1.instance_variable_get("@cached_user").should == @post1.user
|
357
|
+
end
|
358
|
+
|
359
|
+
it "hits the cache only once" do
|
360
|
+
Rails.cache.expects(:read).returns(coder(@post1.user)).once
|
361
|
+
@post1.cached_user.should == @post1.user
|
362
|
+
@post1.cached_user.should == @post1.user
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
describe "has through" do
|
367
|
+
before :each do
|
368
|
+
@user.instance_variable_set("@cached_images", nil)
|
369
|
+
@user.expire_model_cache
|
370
|
+
end
|
371
|
+
|
372
|
+
it "memoizes cache calls" do
|
373
|
+
@user.instance_variable_get("@cached_images").should be_nil
|
374
|
+
@user.cached_images.should == @user.images
|
375
|
+
@user.instance_variable_get("@cached_images").should == @user.images
|
376
|
+
end
|
377
|
+
|
378
|
+
it "hits the cache only once" do
|
379
|
+
Rails.cache.expects(:read).returns(coder(@user.images)).once
|
380
|
+
@user.cached_images.should == @user.images
|
381
|
+
@user.cached_images.should == @user.images
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
describe "has and belongs to many" do
|
386
|
+
before :each do
|
387
|
+
@post1.instance_variable_set("@cached_tags", nil)
|
388
|
+
@post1.expire_model_cache
|
389
|
+
end
|
390
|
+
|
391
|
+
it "memoizes cache calls" do
|
392
|
+
@post1.instance_variable_get("@cached_tags").should be_nil
|
393
|
+
@post1.cached_tags.should == @post1.tags
|
394
|
+
@post1.instance_variable_get("@cached_tags").should == @post1.tags
|
395
|
+
end
|
396
|
+
|
397
|
+
it "hits the cache only once" do
|
398
|
+
Rails.cache.expects(:read).returns(coder(@post1.tags)).once
|
399
|
+
@post1.cached_tags.should == @post1.tags
|
400
|
+
@post1.cached_tags.should == @post1.tags
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
describe "one to many" do
|
405
|
+
before :each do
|
406
|
+
@user.instance_variable_set("@cached_posts", nil)
|
407
|
+
@user.expire_model_cache
|
408
|
+
end
|
409
|
+
|
410
|
+
it "memoizes cache calls" do
|
411
|
+
@user.instance_variable_get("@cached_posts").should be_nil
|
412
|
+
@user.cached_posts.should == @user.posts
|
413
|
+
@user.instance_variable_get("@cached_posts").should == @user.posts
|
414
|
+
end
|
415
|
+
|
416
|
+
it "hits the cache only once" do
|
417
|
+
Rails.cache.expects(:read).returns(coder(@user.posts)).once
|
418
|
+
@user.cached_posts.should == @user.posts
|
419
|
+
@user.cached_posts.should == @user.posts
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
describe "empty polymorphic" do
|
425
|
+
let(:comment) { Comment.new }
|
426
|
+
|
427
|
+
it "should save" do
|
428
|
+
expect {
|
429
|
+
comment.save
|
430
|
+
}.to_not raise_exception
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe "association class name bug" do
|
435
|
+
it "should handle associations with different names" do
|
436
|
+
@user.account.account_location.should == @account_location
|
437
|
+
@user.cached_account.cached_account_location.should == @account_location
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
217
441
|
end
|