jbuilder_cache_multi 0.0.3 → 0.1.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.travis.yml +14 -0
  4. data/Appraisals +1 -1
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +50 -0
  7. data/README.md +6 -0
  8. data/gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile +13 -0
  9. data/gemfiles/rails_3.0.0_jbuilder_1.5.0.gemfile.lock +76 -0
  10. data/gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile +13 -0
  11. data/gemfiles/rails_3.0.0_jbuilder_2.0.0.gemfile.lock +76 -0
  12. data/gemfiles/rails_3.1.0_jbuilder_1.5.0.gemfile +13 -0
  13. data/gemfiles/rails_3.1.0_jbuilder_1.5.0.gemfile.lock +86 -0
  14. data/gemfiles/rails_3.1.0_jbuilder_2.0.0.gemfile +13 -0
  15. data/gemfiles/rails_3.1.0_jbuilder_2.0.0.gemfile.lock +86 -0
  16. data/gemfiles/rails_3.2.0_jbuilder_1.5.0.gemfile +13 -0
  17. data/gemfiles/rails_3.2.0_jbuilder_1.5.0.gemfile.lock +85 -0
  18. data/gemfiles/rails_3.2.0_jbuilder_2.0.0.gemfile +13 -0
  19. data/gemfiles/rails_3.2.0_jbuilder_2.0.0.gemfile.lock +85 -0
  20. data/gemfiles/rails_4.0.0_jbuilder_1.5.0.gemfile +13 -0
  21. data/gemfiles/rails_4.0.0_jbuilder_1.5.0.gemfile.lock +67 -0
  22. data/gemfiles/rails_4.0.0_jbuilder_2.0.0.gemfile +13 -0
  23. data/gemfiles/rails_4.0.0_jbuilder_2.0.0.gemfile.lock +67 -0
  24. data/gemfiles/rails_4.1.0_jbuilder_1.5.0.gemfile +13 -0
  25. data/gemfiles/rails_4.1.0_jbuilder_1.5.0.gemfile.lock +72 -0
  26. data/gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile +13 -0
  27. data/gemfiles/rails_4.1.0_jbuilder_2.0.0.gemfile.lock +72 -0
  28. data/gemfiles/rails_5.0.0_jbuilder_1.5.0.gemfile +13 -0
  29. data/gemfiles/rails_5.0.0_jbuilder_1.5.0.gemfile.lock +87 -0
  30. data/gemfiles/rails_5.0.0_jbuilder_2.0.0.gemfile +13 -0
  31. data/gemfiles/rails_5.0.0_jbuilder_2.0.0.gemfile.lock +87 -0
  32. data/lib/jbuilder_cache_multi/jbuilder_ext.rb +40 -17
  33. data/lib/jbuilder_cache_multi/version.rb +1 -1
  34. data/test/jbuilder_template_test.rb +57 -4
  35. metadata +29 -3
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 4.1.0"
10
+ gem "actionpack", "~> 4.1.0"
11
+ gem "jbuilder", "~> 2.0.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (4.1.13)
11
+ actionview (= 4.1.13)
12
+ activesupport (= 4.1.13)
13
+ rack (~> 1.5.2)
14
+ rack-test (~> 0.6.2)
15
+ actionview (4.1.13)
16
+ activesupport (= 4.1.13)
17
+ builder (~> 3.1)
18
+ erubis (~> 2.7.0)
19
+ activesupport (4.1.13)
20
+ i18n (~> 0.6, >= 0.6.9)
21
+ json (~> 1.7, >= 1.7.7)
22
+ minitest (~> 5.1)
23
+ thread_safe (~> 0.1)
24
+ tzinfo (~> 1.1)
25
+ appraisal (2.1.0)
26
+ bundler
27
+ rake
28
+ thor (>= 0.14.0)
29
+ builder (3.2.2)
30
+ erubis (2.7.0)
31
+ i18n (0.7.0)
32
+ jbuilder (2.0.8)
33
+ activesupport (>= 3.0.0, < 5)
34
+ multi_json (~> 1.2)
35
+ json (1.8.3)
36
+ metaclass (0.0.4)
37
+ minitest (5.8.0)
38
+ mocha (1.1.0)
39
+ metaclass (~> 0.0.1)
40
+ multi_json (1.11.2)
41
+ power_assert (0.2.2)
42
+ rack (1.5.5)
43
+ rack-test (0.6.3)
44
+ rack (>= 1.0)
45
+ railties (4.1.13)
46
+ actionpack (= 4.1.13)
47
+ activesupport (= 4.1.13)
48
+ rake (>= 0.8.7)
49
+ thor (>= 0.18.1, < 2.0)
50
+ rake (10.4.2)
51
+ test-unit (3.0.8)
52
+ power_assert
53
+ thor (0.19.1)
54
+ thread_safe (0.3.5)
55
+ tzinfo (1.2.2)
56
+ thread_safe (~> 0.1)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ actionpack (~> 4.1.0)
63
+ appraisal
64
+ jbuilder (~> 2.0.0)
65
+ jbuilder_cache_multi!
66
+ mocha
67
+ railties (~> 4.1.0)
68
+ rake
69
+ test-unit
70
+
71
+ BUNDLED WITH
72
+ 1.14.6
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 5.0.0"
10
+ gem "actionpack", "~> 5.0.0"
11
+ gem "jbuilder", "~> 1.5.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (5.0.2)
11
+ actionview (= 5.0.2)
12
+ activesupport (= 5.0.2)
13
+ rack (~> 2.0)
14
+ rack-test (~> 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
+ actionview (5.0.2)
18
+ activesupport (= 5.0.2)
19
+ builder (~> 3.1)
20
+ erubis (~> 2.7.0)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
+ activesupport (5.0.2)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (~> 0.7)
26
+ minitest (~> 5.1)
27
+ tzinfo (~> 1.1)
28
+ appraisal (2.2.0)
29
+ bundler
30
+ rake
31
+ thor (>= 0.14.0)
32
+ builder (3.2.3)
33
+ concurrent-ruby (1.0.5)
34
+ erubis (2.7.0)
35
+ i18n (0.8.1)
36
+ jbuilder (1.5.3)
37
+ activesupport (>= 3.0.0)
38
+ multi_json (>= 1.2.0)
39
+ loofah (2.0.3)
40
+ nokogiri (>= 1.5.9)
41
+ metaclass (0.0.4)
42
+ method_source (0.8.2)
43
+ mini_portile2 (2.1.0)
44
+ minitest (5.10.1)
45
+ mocha (1.2.1)
46
+ metaclass (~> 0.0.1)
47
+ multi_json (1.12.1)
48
+ nokogiri (1.7.1)
49
+ mini_portile2 (~> 2.1.0)
50
+ power_assert (1.0.2)
51
+ rack (2.0.2)
52
+ rack-test (0.6.3)
53
+ rack (>= 1.0)
54
+ rails-dom-testing (2.0.2)
55
+ activesupport (>= 4.2.0, < 6.0)
56
+ nokogiri (~> 1.6)
57
+ rails-html-sanitizer (1.0.3)
58
+ loofah (~> 2.0)
59
+ railties (5.0.2)
60
+ actionpack (= 5.0.2)
61
+ activesupport (= 5.0.2)
62
+ method_source
63
+ rake (>= 0.8.7)
64
+ thor (>= 0.18.1, < 2.0)
65
+ rake (12.0.0)
66
+ test-unit (3.2.3)
67
+ power_assert
68
+ thor (0.19.4)
69
+ thread_safe (0.3.6)
70
+ tzinfo (1.2.3)
71
+ thread_safe (~> 0.1)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ actionpack (~> 5.0.0)
78
+ appraisal
79
+ jbuilder (~> 1.5.0)
80
+ jbuilder_cache_multi!
81
+ mocha
82
+ railties (~> 5.0.0)
83
+ rake
84
+ test-unit
85
+
86
+ BUNDLED WITH
87
+ 1.14.6
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "mocha", :require => false
7
+ gem "appraisal"
8
+ gem "test-unit"
9
+ gem "railties", "~> 5.0.0"
10
+ gem "actionpack", "~> 5.0.0"
11
+ gem "jbuilder", "~> 2.0.0"
12
+
13
+ gemspec :path => "../"
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ jbuilder_cache_multi (0.0.3)
5
+ jbuilder (>= 1.5.0, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionpack (5.0.2)
11
+ actionview (= 5.0.2)
12
+ activesupport (= 5.0.2)
13
+ rack (~> 2.0)
14
+ rack-test (~> 0.6.3)
15
+ rails-dom-testing (~> 2.0)
16
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
17
+ actionview (5.0.2)
18
+ activesupport (= 5.0.2)
19
+ builder (~> 3.1)
20
+ erubis (~> 2.7.0)
21
+ rails-dom-testing (~> 2.0)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
23
+ activesupport (5.0.2)
24
+ concurrent-ruby (~> 1.0, >= 1.0.2)
25
+ i18n (~> 0.7)
26
+ minitest (~> 5.1)
27
+ tzinfo (~> 1.1)
28
+ appraisal (2.2.0)
29
+ bundler
30
+ rake
31
+ thor (>= 0.14.0)
32
+ builder (3.2.3)
33
+ concurrent-ruby (1.0.5)
34
+ erubis (2.7.0)
35
+ i18n (0.8.1)
36
+ jbuilder (2.0.5)
37
+ activesupport (>= 3.0.0)
38
+ multi_json (>= 1.2.0)
39
+ loofah (2.0.3)
40
+ nokogiri (>= 1.5.9)
41
+ metaclass (0.0.4)
42
+ method_source (0.8.2)
43
+ mini_portile2 (2.1.0)
44
+ minitest (5.10.1)
45
+ mocha (1.2.1)
46
+ metaclass (~> 0.0.1)
47
+ multi_json (1.12.1)
48
+ nokogiri (1.7.1)
49
+ mini_portile2 (~> 2.1.0)
50
+ power_assert (1.0.2)
51
+ rack (2.0.2)
52
+ rack-test (0.6.3)
53
+ rack (>= 1.0)
54
+ rails-dom-testing (2.0.2)
55
+ activesupport (>= 4.2.0, < 6.0)
56
+ nokogiri (~> 1.6)
57
+ rails-html-sanitizer (1.0.3)
58
+ loofah (~> 2.0)
59
+ railties (5.0.2)
60
+ actionpack (= 5.0.2)
61
+ activesupport (= 5.0.2)
62
+ method_source
63
+ rake (>= 0.8.7)
64
+ thor (>= 0.18.1, < 2.0)
65
+ rake (12.0.0)
66
+ test-unit (3.2.3)
67
+ power_assert
68
+ thor (0.19.4)
69
+ thread_safe (0.3.6)
70
+ tzinfo (1.2.3)
71
+ thread_safe (~> 0.1)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ actionpack (~> 5.0.0)
78
+ appraisal
79
+ jbuilder (~> 2.0.0)
80
+ jbuilder_cache_multi!
81
+ mocha
82
+ railties (~> 5.0.0)
83
+ rake
84
+ test-unit
85
+
86
+ BUNDLED WITH
87
+ 1.14.6
@@ -7,55 +7,78 @@ JbuilderTemplate.class_eval do
7
7
  # json.cache_collection! @people, expires_in: 10.minutes do |person|
8
8
  # json.partial! 'person', :person => person
9
9
  # end
10
- def cache_collection!(collection, options = {}, &block)
11
- if @context.controller.perform_caching
12
- keys_to_collection_map = _keys_to_collection_map(collection, options)
10
+ def cache_collection!(collection, options = {}, &block)
11
+ if @context.controller.perform_caching && !collection.empty?
12
+ keys_to_collection_map = _keys_to_collection_map(collection, options)
13
13
 
14
14
  if ::Rails.cache.respond_to?(:fetch_multi)
15
15
  results = ::Rails.cache.fetch_multi(*keys_to_collection_map.keys, options) do |key|
16
16
  _scope { yield keys_to_collection_map[key] }
17
- end
17
+ end
18
18
  else
19
19
  results = keys_to_collection_map.map do |key, item|
20
20
  ::Rails.cache.fetch(key, options) { _scope { yield item } }
21
21
  end
22
22
  end
23
-
23
+
24
24
  _process_collection_results(results)
25
25
  else
26
26
  array! collection, options, &block
27
27
  end
28
28
  end
29
-
30
-
31
-
29
+
30
+ # Conditionally caches a collection of objects depending in the condition given as first parameter.
31
+ #
32
+ # Example:
33
+ #
34
+ # json.cache_collection_if! do_cache?, @people, expires_in: 10.minutes do |person|
35
+ # json.partial! 'person', :person => person
36
+ # end
37
+ def cache_collection_if!(condition, collection, options = {}, &block)
38
+ condition ?
39
+ cache_collection!(collection, options, &block) :
40
+ array!(collection, options, &block)
41
+ end
42
+
32
43
  protected
33
-
44
+
34
45
  ## Implementing our own version of _cache_key because jbuilder's is protected
35
46
  def _cache_key_fetch_multi(key, options)
47
+ key = _fragment_name_with_digest_fetch_multi(key, options)
48
+ key = url_for(key).split('://', 2).last if ::Hash === key
49
+ ::ActiveSupport::Cache.expand_cache_key(key, :jbuilder)
50
+ end
51
+
52
+ def _fragment_name_with_digest_fetch_multi(key, options)
36
53
  if @context.respond_to?(:cache_fragment_name)
37
54
  # Current compatibility, fragment_name_with_digest is private again and cache_fragment_name
38
55
  # should be used instead.
39
- @context.cache_fragment_name(key, options)
56
+ @context.cache_fragment_name(key, options.slice(:skip_digest, :virtual_path))
40
57
  elsif @context.respond_to?(:fragment_name_with_digest)
41
58
  # Backwards compatibility for period of time when fragment_name_with_digest was made public.
42
59
  @context.fragment_name_with_digest(key)
43
60
  else
44
- ::ActiveSupport::Cache.expand_cache_key(key.is_a?(::Hash) ? url_for(key).split('://').last : key, :jbuilder)
61
+ key
45
62
  end
46
63
  end
47
-
64
+
48
65
  def _keys_to_collection_map(collection, options)
49
66
  key = options.delete(:key)
50
67
 
51
68
  collection.inject({}) do |result, item|
52
- key = key.respond_to?(:call) ? key.call(item) : key
53
- cache_key = key ? [key, item] : item
69
+ cache_key =
70
+ if key.respond_to?(:call)
71
+ key.call(item)
72
+ elsif key
73
+ [key, item]
74
+ else
75
+ item
76
+ end
54
77
  result[_cache_key_fetch_multi(cache_key, options)] = item
55
78
  result
56
79
  end
57
80
  end
58
-
81
+
59
82
  def _process_collection_results(results)
60
83
  _results = results.class == Hash ? results.values : results
61
84
  #support pre 2.0 versions of jbuilder where merge! is still private
@@ -67,5 +90,5 @@ JbuilderTemplate.class_eval do
67
90
  _results
68
91
  end
69
92
  end
70
-
71
- end
93
+
94
+ end
@@ -1,3 +1,3 @@
1
1
  module JbuilderCacheMulti
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -17,7 +17,7 @@ BLOG_POST_PARTIAL = <<-JBUILDER
17
17
  end
18
18
  JBUILDER
19
19
 
20
- CACHE_KEY_PROC = Proc.new { |blog_post| true }
20
+ CACHE_KEY_PROC = Proc.new { |blog_post| blog_post.id }
21
21
 
22
22
  BlogPost = Struct.new(:id, :body, :author_name)
23
23
  blog_authors = [ 'David Heinemeier Hansson', 'Pavel Pravosud' ].cycle
@@ -42,6 +42,14 @@ class JbuilderTemplateTest < ActionView::TestCase
42
42
  }
43
43
  end
44
44
 
45
+ # Stub out a couple of methods that'll get called from cache_fragment_name
46
+ def view_cache_dependencies
47
+ []
48
+ end
49
+ def formats
50
+ [:json]
51
+ end
52
+
45
53
  def render_jbuilder(source)
46
54
  @rendered = []
47
55
  lookup_context.view_paths = [ActionView::FixtureResolver.new(partials.merge('test.json.jbuilder' => source))]
@@ -79,9 +87,18 @@ class JbuilderTemplateTest < ActionView::TestCase
79
87
  assert_collection_rendered json
80
88
  end
81
89
 
90
+ test 'allows additional options' do
91
+ json = render_jbuilder <<-JBUILDER
92
+ json.cache_collection! BLOG_POST_COLLECTION, expires_in: 1.hour do |blog_post|
93
+ json.partial! 'blog_post', :blog_post => blog_post
94
+ end
95
+ JBUILDER
96
+
97
+ assert_collection_rendered json
98
+ end
99
+
82
100
  test 'renders cached array with a key specified as a proc' do
83
101
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
84
- CACHE_KEY_PROC.expects(:call)
85
102
 
86
103
  json = render_jbuilder <<-JBUILDER
87
104
  json.cache_collection! BLOG_POST_COLLECTION, key: CACHE_KEY_PROC do |blog_post|
@@ -91,7 +108,7 @@ class JbuilderTemplateTest < ActionView::TestCase
91
108
 
92
109
  assert_collection_rendered json
93
110
  end
94
-
111
+
95
112
  test 'reverts to cache! if cache does not support fetch_multi' do
96
113
  undef_context_methods :fragment_name_with_digest, :cache_fragment_name
97
114
  ActiveSupport::Cache::Store.send(:undef_method, :fetch_multi) if ActiveSupport::Cache::Store.method_defined?(:fetch_multi)
@@ -104,7 +121,7 @@ class JbuilderTemplateTest < ActionView::TestCase
104
121
 
105
122
  assert_collection_rendered json
106
123
  end
107
-
124
+
108
125
  test 'reverts to array! when controller.perform_caching is false' do
109
126
  controller.perform_caching = false
110
127
 
@@ -117,4 +134,40 @@ class JbuilderTemplateTest < ActionView::TestCase
117
134
  assert_collection_rendered json
118
135
  end
119
136
 
137
+ test 'reverts to array! when collection is empty' do
138
+ json = render_jbuilder <<-JBUILDER
139
+ json.cache_collection! [] do |blog_post|
140
+ json.partial! 'blog_post', :blog_post => blog_post
141
+ end
142
+ JBUILDER
143
+
144
+ assert_equal '[]', json
145
+ end
146
+
147
+ test 'conditionally fragment caching a JSON object' do
148
+ undef_context_methods :fragment_name_with_digest, :cache_fragment_name
149
+
150
+ render_jbuilder <<-JBUILDER
151
+ json.cache_collection_if! true, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
152
+ json.partial! 'blog_post', :blog_post => blog_post
153
+ end
154
+ JBUILDER
155
+
156
+ json = render_jbuilder <<-JBUILDER
157
+ json.cache_collection_if! true, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
158
+ json.test 'Miss'
159
+ end
160
+ JBUILDER
161
+
162
+ assert_collection_rendered json
163
+
164
+ json = render_jbuilder <<-JBUILDER
165
+ json.cache_collection_if! false, BLOG_POST_COLLECTION, key: 'cachekey' do |blog_post|
166
+ json.test 'Miss'
167
+ end
168
+ JBUILDER
169
+
170
+ result = MultiJson.load(json)
171
+ assert_equal 'Miss', result[4]['test']
172
+ end
120
173
  end