simple_cacheable 1.4.1 → 1.5.0
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 +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
|