jbuilder 2.13.0 → 2.14.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23152c62d2a748a3a3b190dba588de44dbb8577aff5ad930fa6aa7e29e935e50
4
- data.tar.gz: 1a79f24f284ede18d9aea34702fe7bff5f70064c8dd6d8a372e8bd9ec4f5d266
3
+ metadata.gz: ea5bb97ea25a962edc387aeeffaeb9dd66622da566f7225543a1492e77328cd9
4
+ data.tar.gz: ad752c5b04270cf297e1e0e0fe41223d886a1042bde3443a37b25215c51347cb
5
5
  SHA512:
6
- metadata.gz: 0fb3a664bd96a0263ed6a155b385a634efcb26e157a1e8d7592da3f3baa1a4ed6d717bead553169d1fd6e540a35f1847925195e07ede281e6d845e6f649cd537
7
- data.tar.gz: c9d1fd1cc89b68ffea4b5b6090ae2ed1de25e75442923a2dc9b16fda0bdfbdb7470d8ada71657d06ad8db1c64c41acacf1e1235891c794c146b3e16758978cff
6
+ metadata.gz: 01dab8d566ba11a9f8baed7972ad962ef4e6090807ff920889e5f4bd64bb69f7d81fe372b3bb243f420222a7742813cd27dd19ba5b213ecd6773a3ff93307a7e
7
+ data.tar.gz: bbf81f248f73b27d20d16de9a313327f7d82024c2304177cad74ff000942be69c1f43435c9e9cc6126499119e36d4c327750489e9e8f6add0658eb8928d16780
@@ -0,0 +1,25 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3
+ {
4
+ "name": "jbuilder",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "ghcr.io/rails/devcontainer/images/ruby:3.4.5",
7
+ "features": {
8
+ "ghcr.io/devcontainers/features/github-cli:1": {}
9
+ }
10
+
11
+ // Features to add to the dev container. More info: https://containers.dev/features.
12
+ // "features": {},
13
+
14
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
15
+ // "forwardPorts": [],
16
+
17
+ // Use 'postCreateCommand' to run commands after the container is created.
18
+ // "postCreateCommand": "ruby --version",
19
+
20
+ // Configure tool-specific properties.
21
+ // "customizations": {},
22
+
23
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
24
+ // "remoteUser": "root"
25
+ }
@@ -5,7 +5,7 @@ on: [push, pull_request]
5
5
  jobs:
6
6
  test:
7
7
  name: Ruby ${{ matrix.ruby }} (${{ matrix.gemfile }})
8
- runs-on: ubuntu-20.04
8
+ runs-on: ubuntu-latest
9
9
  continue-on-error: ${{ matrix.gemfile == 'rails_head' }}
10
10
  env:
11
11
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
@@ -19,23 +19,30 @@ jobs:
19
19
  - "3.1"
20
20
  - "3.2"
21
21
  - "3.3"
22
+ - "3.4"
22
23
 
23
24
  gemfile:
24
25
  - "rails_7_0"
25
26
  - "rails_7_1"
27
+ - "rails_7_2"
28
+ - "rails_8_0"
26
29
  - "rails_head"
27
30
 
28
31
  exclude:
32
+ - ruby: '3.0'
33
+ gemfile: rails_7_2
34
+ - ruby: '3.0'
35
+ gemfile: rails_8_0
29
36
  - ruby: '3.0'
30
37
  gemfile: rails_head
31
-
32
- include:
38
+ - ruby: '3.1'
39
+ gemfile: rails_7_2
40
+ - ruby: '3.1'
41
+ gemfile: rails_8_0
33
42
  - ruby: '3.1'
34
43
  gemfile: rails_head
35
- - ruby: '3.2'
36
- gemfile: rails_head
37
- - ruby: head
38
- gemfile: rails_head
44
+ - ruby: '3.4'
45
+ gemfile: rails_7_0
39
46
 
40
47
  steps:
41
48
  - uses: actions/checkout@v4
data/Appraisals CHANGED
@@ -1,13 +1,22 @@
1
- if RUBY_VERSION >= "2.7.0"
2
- appraise "rails-7-0" do
3
- gem "rails", "~> 7.0.0"
4
- end
5
-
6
- appraise "rails-7-1" do
7
- gem "rails", "~> 7.1.0"
8
- end
9
-
10
- appraise "rails-head" do
11
- gem "rails", github: "rails/rails", branch: "main"
12
- end
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rails-7-0" do
4
+ gem "rails", "~> 7.0.0"
5
+ gem "concurrent-ruby", "< 1.3.5" # to avoid problem described in https://github.com/rails/rails/pull/54264
6
+ end
7
+
8
+ appraise "rails-7-1" do
9
+ gem "rails", "~> 7.1.0"
10
+ end
11
+
12
+ appraise "rails-7-2" do
13
+ gem "rails", "~> 7.2.0"
14
+ end
15
+
16
+ appraise "rails-8-0" do
17
+ gem "rails", "~> 8.0.0"
18
+ end
19
+
20
+ appraise "rails-head" do
21
+ gem "rails", github: "rails/rails", branch: "main"
13
22
  end
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  gemspec
data/README.md CHANGED
@@ -5,7 +5,7 @@ manipulating giant hash structures. This is particularly helpful when the
5
5
  generation process is fraught with conditionals and loops. Here's a simple
6
6
  example:
7
7
 
8
- ``` ruby
8
+ ```ruby
9
9
  # app/views/messages/show.json.jbuilder
10
10
 
11
11
  json.content format_content(@message.content)
@@ -31,7 +31,7 @@ end
31
31
 
32
32
  This will build the following structure:
33
33
 
34
- ``` javascript
34
+ ```javascript
35
35
  {
36
36
  "content": "<p>This is <i>serious</i> monkey business</p>",
37
37
  "created_at": "2011-10-29T20:45:28-05:00",
@@ -57,9 +57,11 @@ This will build the following structure:
57
57
  }
58
58
  ```
59
59
 
60
+ ## Dynamically Defined Attributes
61
+
60
62
  To define attribute and structure names dynamically, use the `set!` method:
61
63
 
62
- ``` ruby
64
+ ```ruby
63
65
  json.set! :author do
64
66
  json.set! :name, 'David'
65
67
  end
@@ -67,10 +69,11 @@ end
67
69
  # => {"author": { "name": "David" }}
68
70
  ```
69
71
 
72
+ ## Merging Existing Hash or Array
70
73
 
71
74
  To merge existing hash or array to current context:
72
75
 
73
- ``` ruby
76
+ ```ruby
74
77
  hash = { author: { name: "David" } }
75
78
  json.post do
76
79
  json.title "Merge HOWTO"
@@ -80,9 +83,11 @@ end
80
83
  # => "post": { "title": "Merge HOWTO", "author": { "name": "David" } }
81
84
  ```
82
85
 
83
- Top level arrays can be handled directly. Useful for index and other collection actions.
86
+ ## Top Level Arrays
87
+
88
+ Top level arrays can be handled directly. Useful for index and other collection actions.
84
89
 
85
- ``` ruby
90
+ ```ruby
86
91
  # @comments = @post.comments
87
92
 
88
93
  json.array! @comments do |comment|
@@ -98,9 +103,11 @@ end
98
103
  # => [ { "body": "great post...", "author": { "first_name": "Joe", "last_name": "Bloe" }} ]
99
104
  ```
100
105
 
106
+ ## Array Attributes
107
+
101
108
  You can also extract attributes from array directly.
102
109
 
103
- ``` ruby
110
+ ```ruby
104
111
  # @people = People.all
105
112
 
106
113
  json.array! @people, :id, :name
@@ -108,6 +115,8 @@ json.array! @people, :id, :name
108
115
  # => [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ]
109
116
  ```
110
117
 
118
+ ## Plain Arrays
119
+
111
120
  To make a plain array without keys, construct and pass in a standard Ruby array.
112
121
 
113
122
  ```ruby
@@ -118,6 +127,8 @@ json.people my_array
118
127
  # => "people": [ "David", "Jamie" ]
119
128
  ```
120
129
 
130
+ ## Child Objects
131
+
121
132
  You don't always have or need a collection when building an array.
122
133
 
123
134
  ```ruby
@@ -135,9 +146,11 @@ end
135
146
  # => { "people": [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ] }
136
147
  ```
137
148
 
138
- Jbuilder objects can be directly nested inside each other. Useful for composing objects.
149
+ ## Nested Jbuilder Objects
150
+
151
+ Jbuilder objects can be directly nested inside each other. Useful for composing objects.
139
152
 
140
- ``` ruby
153
+ ```ruby
141
154
  class Person
142
155
  # ... Class Definition ... #
143
156
  def to_builder
@@ -163,11 +176,13 @@ company.to_builder.target!
163
176
  # => {"name":"Doodle Corp","president":{"name":"John Stobs","age":58}}
164
177
  ```
165
178
 
179
+ ## Rails Integration
180
+
166
181
  You can either use Jbuilder stand-alone or directly as an ActionView template
167
182
  language. When required in Rails, you can create views à la show.json.jbuilder
168
183
  (the json is already yielded):
169
184
 
170
- ``` ruby
185
+ ```ruby
171
186
  # Any helpers available to views are available to the builder
172
187
  json.content format_content(@message.content)
173
188
  json.(@message, :created_at, :updated_at)
@@ -183,6 +198,8 @@ if current_user.admin?
183
198
  end
184
199
  ```
185
200
 
201
+ ## Partials
202
+
186
203
  You can use partials as well. The following will render the file
187
204
  `views/comments/_comments.json.jbuilder`, and set a local variable
188
205
  `comments` with all this message's comments, which you can use inside
@@ -215,15 +232,15 @@ then the object is passed to the partial as the variable `some_symbol`.
215
232
  Be sure not to confuse the `as:` option to mean nesting of the partial. For example:
216
233
 
217
234
  ```ruby
218
- # Use the default `views/comments/_comment.json.jbuilder`, putting @comment as the comment local variable.
219
- # Note, `comment` attributes are "inlined".
220
- json.partial! @comment, as: :comment
235
+ # Use the default `views/comments/_comment.json.jbuilder`, putting @comment as the comment local variable.
236
+ # Note, `comment` attributes are "inlined".
237
+ json.partial! @comment, as: :comment
221
238
  ```
222
239
 
223
240
  is quite different from:
224
241
 
225
242
  ```ruby
226
- # comment attributes are nested under a "comment" property
243
+ # comment attributes are nested under a "comment" property
227
244
  json.comment do
228
245
  json.partial! "/comments/comment.json.jbuilder", comment: @comment
229
246
  end
@@ -239,10 +256,11 @@ json.partial! 'sub_template', locals: { user: user }
239
256
  json.partial! 'sub_template', user: user
240
257
  ```
241
258
 
259
+ ## Null Values
242
260
 
243
261
  You can explicitly make Jbuilder object return null if you want:
244
262
 
245
- ``` ruby
263
+ ```ruby
246
264
  json.extract! @post, :id, :title, :content, :published_at
247
265
  json.author do
248
266
  if @post.anonymous?
@@ -305,7 +323,7 @@ This will include both records as part of the cache key and updating either of t
305
323
  Keys can be auto formatted using `key_format!`, this can be used to convert
306
324
  keynames from the standard ruby_format to camelCase:
307
325
 
308
- ``` ruby
326
+ ```ruby
309
327
  json.key_format! camelize: :lower
310
328
  json.first_name 'David'
311
329
 
@@ -315,7 +333,7 @@ json.first_name 'David'
315
333
  You can set this globally with the class method `key_format` (from inside your
316
334
  environment.rb for example):
317
335
 
318
- ``` ruby
336
+ ```ruby
319
337
  Jbuilder.key_format camelize: :lower
320
338
  ```
321
339
 
@@ -323,7 +341,7 @@ By default, key format is not applied to keys of hashes that are
323
341
  passed to methods like `set!`, `array!` or `merge!`. You can opt into
324
342
  deeply transforming these as well:
325
343
 
326
- ``` ruby
344
+ ```ruby
327
345
  json.key_format! camelize: :lower
328
346
  json.deep_format_keys!
329
347
  json.settings([{some_value: "abc"}])
@@ -334,7 +352,7 @@ json.settings([{some_value: "abc"}])
334
352
  You can set this globally with the class method `deep_format_keys` (from inside your
335
353
  environment.rb for example):
336
354
 
337
- ``` ruby
355
+ ```ruby
338
356
  Jbuilder.deep_format_keys true
339
357
  ```
340
358
 
@@ -350,4 +368,5 @@ features and discuss issues.
350
368
  See [CONTRIBUTING](CONTRIBUTING.md).
351
369
 
352
370
  ## License
371
+
353
372
  Jbuilder is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/setup"
2
4
  require "bundler/gem_tasks"
3
5
  require "rake/testtask"
data/bin/test CHANGED
@@ -1,4 +1,4 @@
1
- #!/bin/env bash
1
+ #!/usr/bin/env bash
2
2
  set -e
3
3
 
4
4
  bundle install
@@ -6,5 +6,6 @@ gem "rake"
6
6
  gem "mocha", require: false
7
7
  gem "appraisal"
8
8
  gem "rails", "~> 7.0.0"
9
+ gem "concurrent-ruby", "< 1.3.5"
9
10
 
10
11
  gemspec path: "../"
@@ -0,0 +1,10 @@
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 "rails", "~> 7.2.0"
9
+
10
+ gemspec path: "../"
@@ -0,0 +1,10 @@
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 "rails", "~> 8.0.0"
9
+
10
+ gemspec path: "../"
data/jbuilder.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "lib/jbuilder/version"
2
4
 
3
5
  Gem::Specification.new do |s|
@@ -9,10 +11,10 @@ Gem::Specification.new do |s|
9
11
  s.homepage = 'https://github.com/rails/jbuilder'
10
12
  s.license = 'MIT'
11
13
 
12
- s.required_ruby_version = '>= 2.2.2'
14
+ s.required_ruby_version = '>= 3.0.0'
13
15
 
14
- s.add_dependency 'activesupport', '>= 5.0.0'
15
- s.add_dependency 'actionview', '>= 5.0.0'
16
+ s.add_dependency 'activesupport', '>= 7.0.0'
17
+ s.add_dependency 'actionview', '>= 7.0.0'
16
18
 
17
19
  if RUBY_ENGINE == 'rbx'
18
20
  s.add_development_dependency('racc')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/named_base'
2
4
  require 'rails/generators/resource_helpers'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators'
2
4
  require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
3
5
 
@@ -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 <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully updated.") %> }
46
+ format.html { redirect_to <%= redirect_resource_name %>, notice: <%= %("#{human_name} was successfully updated.") %>, status: :see_other }
47
47
  format.json { render :show, status: :ok, location: <%= "@#{singular_table_name}" %> }
48
48
  else
49
49
  format.html { render :edit, status: :unprocessable_entity }
@@ -57,7 +57,7 @@ class <%= controller_class_name %>Controller < ApplicationController
57
57
  @<%= orm_instance.destroy %>
58
58
 
59
59
  respond_to do |format|
60
- format.html { redirect_to <%= index_helper %>_path, status: :see_other, notice: <%= %("#{human_name} was successfully destroyed.") %> }
60
+ format.html { redirect_to <%= index_helper %>_path, notice: <%= %("#{human_name} was successfully destroyed.") %>, status: :see_other }
61
61
  format.json { head :no_content }
62
62
  end
63
63
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Jbuilder
2
4
  class Blank
3
5
  def ==(other)
@@ -1,37 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'delegate'
2
- require 'active_support/concern'
3
4
  require 'action_view'
4
-
5
- begin
6
- require 'action_view/renderer/collection_renderer'
7
- rescue LoadError
8
- require 'action_view/renderer/partial_renderer'
9
- end
5
+ require 'action_view/renderer/collection_renderer'
10
6
 
11
7
  class Jbuilder
12
- module CollectionRenderable # :nodoc:
13
- extend ActiveSupport::Concern
14
-
15
- class_methods do
16
- def supported?
17
- superclass.private_method_defined?(:build_rendered_template) && self.superclass.private_method_defined?(:build_rendered_collection)
18
- end
19
- end
20
-
21
- private
22
-
23
- def build_rendered_template(content, template, layout = nil)
24
- super(content || json.attributes!, template)
25
- end
26
-
27
- def build_rendered_collection(templates, _spacer)
28
- json.merge!(templates.map(&:body))
29
- end
30
-
31
- def json
32
- @options[:locals].fetch(:json)
33
- end
34
-
8
+ class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
35
9
  class ScopedIterator < ::SimpleDelegator # :nodoc:
36
10
  include Enumerable
37
11
 
@@ -40,16 +14,6 @@ class Jbuilder
40
14
  @scope = scope
41
15
  end
42
16
 
43
- # Rails 6.0 support:
44
- def each
45
- return enum_for(:each) unless block_given?
46
-
47
- __getobj__.each do |object|
48
- @scope.call { yield(object) }
49
- end
50
- end
51
-
52
- # Rails 6.1 support:
53
17
  def each_with_info
54
18
  return enum_for(:each_with_info) unless block_given?
55
19
 
@@ -60,51 +24,29 @@ class Jbuilder
60
24
  end
61
25
 
62
26
  private_constant :ScopedIterator
63
- end
64
-
65
- if defined?(::ActionView::CollectionRenderer)
66
- # Rails 6.1 support:
67
- class CollectionRenderer < ::ActionView::CollectionRenderer # :nodoc:
68
- include CollectionRenderable
69
27
 
70
- def initialize(lookup_context, options, &scope)
71
- super(lookup_context, options)
72
- @scope = scope
73
- end
74
-
75
- private
76
- def collection_with_template(view, template, layout, collection)
77
- super(view, template, layout, ScopedIterator.new(collection, @scope))
78
- end
28
+ def initialize(lookup_context, options, &scope)
29
+ super(lookup_context, options)
30
+ @scope = scope
79
31
  end
80
- else
81
- # Rails 6.0 support:
82
- class CollectionRenderer < ::ActionView::PartialRenderer # :nodoc:
83
- include CollectionRenderable
84
32
 
85
- def initialize(lookup_context, options, &scope)
86
- super(lookup_context)
87
- @options = options
88
- @scope = scope
89
- end
33
+ private
90
34
 
91
- def render_collection_with_partial(collection, partial, context, block)
92
- render(context, @options.merge(collection: collection, partial: partial), block)
35
+ def build_rendered_template(content, template, layout = nil)
36
+ super(content || json.attributes!, template)
93
37
  end
94
38
 
95
- private
96
- def collection_without_template(view)
97
- @collection = ScopedIterator.new(@collection, @scope)
98
-
99
- super(view)
100
- end
39
+ def build_rendered_collection(templates, _spacer)
40
+ json.merge!(templates.map(&:body))
41
+ end
101
42
 
102
- def collection_with_template(view, template)
103
- @collection = ScopedIterator.new(@collection, @scope)
43
+ def json
44
+ @options[:locals].fetch(:json)
45
+ end
104
46
 
105
- super(view, template)
106
- end
107
- end
47
+ def collection_with_template(view, template, layout, collection)
48
+ super(view, template, layout, ScopedIterator.new(collection, @scope))
49
+ end
108
50
  end
109
51
 
110
52
  class EnumerableCompat < ::SimpleDelegator
@@ -1,4 +1,6 @@
1
- require 'jbuilder/jbuilder'
1
+ # frozen_string_literal: true
2
+
3
+ require 'jbuilder/version'
2
4
 
3
5
  class Jbuilder
4
6
  class NullError < ::NoMethodError
@@ -1 +1,3 @@
1
- Jbuilder = Class.new(BasicObject)
1
+ # frozen_string_literal: true
2
+
3
+ require 'jbuilder/version'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Jbuilder::DependencyTracker
2
4
  EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/
3
5