jbuilder 2.11.3 → 2.11.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dacba51a263fc3bcbea4471ae1557dea10c014f68657a39ab812e55a167eba9
4
- data.tar.gz: 544f954ce6f89f7775853b91bfc99f5f1634596389f5750028e13532b314a63c
3
+ metadata.gz: 071e52598986c430c4bc79a185a0229eceb11c3f38f12ee5a6bd6f9c16f7008c
4
+ data.tar.gz: 73e82bf90e7049fb735ba139521daf1e0291fbd8e704a1523f7aa4f97e395185
5
5
  SHA512:
6
- metadata.gz: a71638ae38f5755b97a40db81c2121f92788b3e4242de6d4789032f0ff7bab4f62d2dd96b7cab19e8583ee448946bb2e66e8cf5f6ab65c7b514ff88c19af1407
7
- data.tar.gz: cd3477c065ebdbacc5da5d383973e996499cce7872d8303691376739732735441b003981a767af1bdb8ccea6648685291ff20e81c662a95ad54c87205ba233f9
6
+ metadata.gz: fca112fc608e7fee45bc1b90ddb5430205d462955f458d1c5fff0d3d716a40ddd7cfc3383465f2eb727b82bfb3b1b226508df7ae77779c3655661324ee8d4963
7
+ data.tar.gz: 5a250b8e997d56eeeef8b3630cbdc98a6b88e78c06cd3524fb0f5518939ed10ff38bcb9dcc9c8470925f881c5b0690298af019ff16db4a162bee3207f5e6bfd6
@@ -4,7 +4,7 @@ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  test:
7
- name: Ruby test
7
+ name: Ruby ${{ matrix.ruby }} (${{ matrix.gemfile }})
8
8
  runs-on: ubuntu-20.04
9
9
  continue-on-error: ${{ matrix.experimental }}
10
10
  env:
@@ -14,82 +14,82 @@ jobs:
14
14
  strategy:
15
15
  fail-fast: false
16
16
  matrix:
17
- ruby: [
18
- 2.2.10,
19
- 2.3.8,
20
- 2.4.10,
21
- 2.5.8,
22
- 2.6.6,
23
- 2.7.1,
24
- 3.0.0
25
- ]
26
- gemfile: [
27
- "rails_5_0",
28
- "rails_5_1",
29
- "rails_5_2",
30
- "rails_6_0",
31
- "rails_6_1",
32
- "rails_head"
33
- ]
17
+ ruby:
18
+ - "2.2"
19
+ - "2.3"
20
+ - "2.4"
21
+ - "2.5"
22
+ - "2.6"
23
+ - "2.7"
24
+ - "3.0"
25
+
26
+ gemfile:
27
+ - "rails_5_0"
28
+ - "rails_5_1"
29
+ - "rails_5_2"
30
+ - "rails_6_0"
31
+ - "rails_6_1"
32
+ - "rails_head"
33
+
34
34
  experimental: [false]
35
35
  exclude:
36
- - ruby: 2.7.1
36
+ - ruby: 2.7
37
37
  gemfile: rails_5_0
38
- - ruby: 3.0.0
38
+ - ruby: '3.0'
39
39
  gemfile: rails_5_0
40
40
  - ruby: head
41
41
  gemfile: rails_5_0
42
- - ruby: 2.7.1
42
+ - ruby: 2.7
43
43
  gemfile: rails_5_1
44
- - ruby: 3.0.0
44
+ - ruby: '3.0'
45
45
  gemfile: rails_5_1
46
46
  - ruby: head
47
47
  gemfile: rails_5_1
48
- - ruby: 2.2.10
48
+ - ruby: 2.2
49
49
  gemfile: rails_5_2
50
- - ruby: 2.7.1
50
+ - ruby: 2.7
51
51
  gemfile: rails_5_2
52
- - ruby: 3.0.0
52
+ - ruby: '3.0'
53
53
  gemfile: rails_5_2
54
54
  - ruby: head
55
55
  gemfile: rails_5_2
56
- - ruby: 2.2.10
56
+ - ruby: 2.2
57
57
  gemfile: rails_6_0
58
- - ruby: 2.3.8
58
+ - ruby: 2.3
59
59
  gemfile: rails_6_0
60
- - ruby: 2.4.10
60
+ - ruby: 2.4
61
61
  gemfile: rails_6_0
62
- - ruby: 3.0.0
62
+ - ruby: '3.0'
63
63
  gemfile: rails_6_0
64
64
  - ruby: head
65
65
  gemfile: rails_6_0
66
- - ruby: 2.2.10
66
+ - ruby: 2.2
67
67
  gemfile: rails_6_1
68
- - ruby: 2.3.8
68
+ - ruby: 2.3
69
69
  gemfile: rails_6_1
70
- - ruby: 2.4.10
70
+ - ruby: 2.4
71
71
  gemfile: rails_6_1
72
- - ruby: 2.2.10
72
+ - ruby: 2.2
73
73
  gemfile: rails_head
74
- - ruby: 2.3.8
74
+ - ruby: 2.3
75
75
  gemfile: rails_head
76
- - ruby: 2.4.10
76
+ - ruby: 2.4
77
77
  gemfile: rails_head
78
- - ruby: 2.5.8
78
+ - ruby: 2.5
79
79
  gemfile: rails_head
80
- - ruby: 2.6.6
80
+ - ruby: 2.6
81
81
  gemfile: rails_head
82
- - ruby: 2.7.1
82
+ - ruby: 2.7
83
83
  gemfile: rails_head
84
84
  experimental: false
85
- - ruby: 3.0.0
85
+ - ruby: '3.0'
86
86
  gemfile: rails_head
87
87
  experimental: false
88
88
  include:
89
- - ruby: 2.7.1
89
+ - ruby: 2.7
90
90
  gemfile: rails_head
91
91
  experimental: true
92
- - ruby: 3.0.0
92
+ - ruby: '3.0'
93
93
  gemfile: rails_head
94
94
  experimental: true
95
95
  - ruby: head
data/README.md CHANGED
@@ -110,12 +110,13 @@ json.array! @people, :id, :name
110
110
 
111
111
  To make a plain array without keys, construct and pass in a standard Ruby array.
112
112
 
113
- ``` ruby
113
+ ```ruby
114
114
  my_array = %w(David Jamie)
115
115
 
116
116
  json.people my_array
117
117
 
118
118
  # => "people": [ "David", "Jamie" ]
119
+ ```
119
120
 
120
121
  You don't always have or need a collection when building an array.
121
122
 
@@ -284,13 +285,21 @@ end
284
285
  Aside from that, the `:cached` options on collection rendering is available on Rails >= 6.0. This will cache the
285
286
  rendered results effectively using the multi fetch feature.
286
287
 
287
- ```
288
+ ```ruby
288
289
  json.array! @posts, partial: "posts/post", as: :post, cached: true
289
290
 
290
291
  # or:
291
292
  json.comments @post.comments, partial: "comments/comment", as: :comment, cached: true
292
293
  ```
293
294
 
295
+ If your collection cache depends on multiple sources (try to avoid this to keep things simple), you can name all these dependencies as part of a block that returns an array:
296
+
297
+ ```ruby
298
+ json.array! @posts, partial: "posts/post", as: :post, cached: -> post { [post, current_user] }
299
+ ```
300
+
301
+ This will include both records as part of the cache key and updating either of them will expire the cache.
302
+
294
303
  ## Formatting Keys
295
304
 
296
305
  Keys can be auto formatted using `key_format!`, this can be used to convert
data/jbuilder.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jbuilder'
3
- s.version = '2.11.3'
3
+ s.version = '2.11.4'
4
4
  s.authors = 'David Heinemeier Hansson'
5
5
  s.email = 'david@basecamp.com'
6
6
  s.summary = 'Create JSON structures via a Builder-style DSL'
@@ -30,7 +30,7 @@ class <%= controller_class_name %>Controller < ApplicationController
30
30
 
31
31
  respond_to do |format|
32
32
  if @<%= orm_instance.save %>
33
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= %("#{human_name} was successfully created.") %> }
33
+ format.html { redirect_to <%= show_helper %>, notice: <%= %("#{human_name} was successfully created.") %> }
34
34
  format.json { render :show, status: :created, location: <%= "@#{singular_table_name}" %> }
35
35
  else
36
36
  format.html { render :new, status: :unprocessable_entity }
@@ -43,7 +43,7 @@ class <%= controller_class_name %>Controller < ApplicationController
43
43
  def update
44
44
  respond_to do |format|
45
45
  if @<%= orm_instance.update("#{singular_table_name}_params") %>
46
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= %("#{human_name} was successfully updated.") %> }
46
+ format.html { redirect_to <%= show_helper %>, notice: <%= %("#{human_name} was successfully updated.") %> }
47
47
  format.json { render :show, status: :ok, location: <%= "@#{singular_table_name}" %> }
48
48
  else
49
49
  format.html { render :edit, status: :unprocessable_entity }
@@ -55,6 +55,7 @@ class <%= controller_class_name %>Controller < ApplicationController
55
55
  # DELETE <%= route_url %>/1 or <%= route_url %>/1.json
56
56
  def destroy
57
57
  @<%= orm_instance.destroy %>
58
+
58
59
  respond_to do |format|
59
60
  format.html { redirect_to <%= index_helper %>_url, notice: <%= %("#{human_name} was successfully destroyed.") %> }
60
61
  format.json { head :no_content }
@@ -141,9 +141,7 @@ class JbuilderTemplate < Jbuilder
141
141
  options.reverse_merge! ::JbuilderTemplate.template_lookup_options
142
142
  as = options[:as]
143
143
 
144
- if options.key?(:collection) && (options[:collection].nil? || options[:collection].empty?)
145
- array!
146
- elsif as && options.key?(:collection) && CollectionRenderer.supported?
144
+ if as && options.key?(:collection) && CollectionRenderer.supported?
147
145
  collection = options.delete(:collection) || []
148
146
  partial = options.delete(:partial)
149
147
  options[:locals].merge!(json: self)
@@ -156,9 +154,11 @@ class JbuilderTemplate < Jbuilder
156
154
  raise ::NotImplementedError, "The `:spacer_template' option is not supported in collection rendering."
157
155
  end
158
156
 
159
- CollectionRenderer
157
+ results = CollectionRenderer
160
158
  .new(@context.lookup_context, options) { |&block| _scope(&block) }
161
159
  .render_collection_with_partial(collection, partial, @context, nil)
160
+
161
+ array! if results.respond_to?(:body) && results.body.nil?
162
162
  elsif as && options.key?(:collection) && !CollectionRenderer.supported?
163
163
  # For Rails <= 5.2:
164
164
  as = as.to_sym
@@ -291,6 +291,22 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
291
291
  assert_equal [], result
292
292
  end
293
293
 
294
+ test "works with an enumerable object" do
295
+ enumerable_class = Class.new do
296
+ include Enumerable
297
+ alias length count # Rails 6.1 requires this.
298
+
299
+ def each(&block)
300
+ [].each(&block)
301
+ end
302
+ end
303
+
304
+ result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: enumerable_class.new)
305
+
306
+ # Do not use #assert_empty as it is important to ensure that the type of the JSON result is an array.
307
+ assert_equal [], result
308
+ end
309
+
294
310
  test "supports the cached: true option" do
295
311
  result = render('json.array! @posts, partial: "post", as: :post, cached: true', posts: POSTS)
296
312
 
@@ -318,6 +334,33 @@ class JbuilderTemplateTest < ActiveSupport::TestCase
318
334
  assert_equal "Pavel", result[5]["author"]["first_name"]
319
335
  end
320
336
 
337
+ test "supports the cached: ->() {} option" do
338
+ result = render('json.array! @posts, partial: "post", as: :post, cached: ->(post) { [post, "foo"] }', posts: POSTS)
339
+
340
+ assert_equal 10, result.count
341
+ assert_equal "Post #5", result[4]["body"]
342
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
343
+ assert_equal "Pavel", result[5]["author"]["first_name"]
344
+
345
+ expected = {
346
+ "id" => 1,
347
+ "body" => "Post #1",
348
+ "author" => {
349
+ "first_name" => "David",
350
+ "last_name" => "Heinemeier Hansson"
351
+ }
352
+ }
353
+
354
+ assert_equal expected, Rails.cache.read("post-1/foo")
355
+
356
+ result = render('json.array! @posts, partial: "post", as: :post, cached: ->(post) { [post, "foo"] }', posts: POSTS)
357
+
358
+ assert_equal 10, result.count
359
+ assert_equal "Post #5", result[4]["body"]
360
+ assert_equal "Heinemeier Hansson", result[2]["author"]["last_name"]
361
+ assert_equal "Pavel", result[5]["author"]["first_name"]
362
+ end
363
+
321
364
  test "raises an error on a render call with the :layout option" do
322
365
  error = assert_raises NotImplementedError do
323
366
  render('json.array! @posts, partial: "post", as: :post, layout: "layout"', posts: POSTS)
@@ -31,14 +31,14 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
31
31
  assert_instance_method :create, content do |m|
32
32
  assert_match %r{@post = Post\.new\(post_params\)}, m
33
33
  assert_match %r{@post\.save}, m
34
- assert_match %r{format\.html \{ redirect_to @post, notice: "Post was successfully created\." \}}, m
34
+ assert_match %r{format\.html \{ redirect_to post_url\(@post\), notice: "Post was successfully created\." \}}, m
35
35
  assert_match %r{format\.json \{ render :show, status: :created, location: @post \}}, m
36
36
  assert_match %r{format\.html \{ render :new, status: :unprocessable_entity \}}, m
37
37
  assert_match %r{format\.json \{ render json: @post\.errors, status: :unprocessable_entity \}}, m
38
38
  end
39
39
 
40
40
  assert_instance_method :update, content do |m|
41
- assert_match %r{format\.html \{ redirect_to @post, notice: "Post was successfully updated\." \}}, m
41
+ assert_match %r{format\.html \{ redirect_to post_url\(@post\), notice: "Post was successfully updated\." \}}, m
42
42
  assert_match %r{format\.json \{ render :show, status: :ok, location: @post \}}, m
43
43
  assert_match %r{format\.html \{ render :edit, status: :unprocessable_entity \}}, m
44
44
  assert_match %r{format\.json \{ render json: @post.errors, status: :unprocessable_entity \}}, m
@@ -59,6 +59,25 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
59
59
  end
60
60
  end
61
61
 
62
+ if Rails::VERSION::MAJOR >= 6
63
+ test 'controller with namespace' do
64
+ run_generator %w(Admin::Post --model-name=Post)
65
+ assert_file 'app/controllers/admin/posts_controller.rb' do |content|
66
+ assert_instance_method :create, content do |m|
67
+ assert_match %r{format\.html \{ redirect_to admin_post_url\(@post\), notice: "Post was successfully created\." \}}, m
68
+ end
69
+
70
+ assert_instance_method :update, content do |m|
71
+ assert_match %r{format\.html \{ redirect_to admin_post_url\(@post\), notice: "Post was successfully updated\." \}}, m
72
+ end
73
+
74
+ assert_instance_method :destroy, content do |m|
75
+ assert_match %r{format\.html \{ redirect_to admin_posts_url, notice: "Post was successfully destroyed\." \}}, m
76
+ end
77
+ end
78
+ end
79
+ end
80
+
62
81
  test "don't use require and permit if there are no attributes" do
63
82
  run_generator %w(Post)
64
83
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.3
4
+ version: 2.11.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-14 00:00:00.000000000 Z
11
+ date: 2021-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  requirements: []
91
- rubygems_version: 3.2.22
91
+ rubygems_version: 3.2.32
92
92
  signing_key:
93
93
  specification_version: 4
94
94
  summary: Create JSON structures via a Builder-style DSL