jbuilder 2.11.3 → 2.11.4

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 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