jbuilder 2.10.1 → 2.11.1

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: c33305909a9aa4be64b5dd83da1f6a5570654ab50a38042ae404da406f06cca3
4
- data.tar.gz: 5cc79921463b6cef4f7dbc37dba911e47a6a826824223a4b89a289f6ccf59dea
3
+ metadata.gz: 3e3eebf3fe3849616361ae7df9556f466eaf84da813756b8690dfbd5c28d41a1
4
+ data.tar.gz: 011c0162b09a94f229673e88bab0d0d466d9552a004afb426f817a02c3af8943
5
5
  SHA512:
6
- metadata.gz: 5f2a7e1ed17babb16527afb6e12458ddadcbd5bb2129c110d4e426f573db610d2cc3f9d9d7d06c577c7608c97016c1ec5a60431237362c7d955d0674dcba2de3
7
- data.tar.gz: cf0820dc816f84fde3a2fa17010ce05e325bba7a830d4a0b7b26dafeafe17a73d2ce6734e7a0f3af54389f304439e58206897efa38bc97c63ba184b545f86ab3
6
+ metadata.gz: 29968e2f35da52dc00db229d0085d77a7d390417bbe3011b005824ff45a1291bca0f45c59d4f40263a3ac236e31ea3fdd0cd78ba01ddef4e51414aea4ac34704
7
+ data.tar.gz: '09df7fb01ce2d128b0f45116cc4f2ccb01469031a51b598f6c17c16f58ddbd0c3059095a1a6761a2f26e328b3960def55752d6ed36cca0e2952e393d712e48b3'
@@ -1,12 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ 2.11.1
4
+ ------
5
+
6
+ * Use symbols instead of strings for before_action fitlers [DHH]
7
+ * Slim down comments in generated scaffold code [DHH]
8
+
9
+ 2.11.0
10
+ ------
11
+
12
+ * [Allow jbuilder instance to be passed to #merge!](https://github.com/rails/jbuilder/pull/485)
13
+ * [Fix for key_format! when using nested hashes](https://github.com/rails/jbuilder/pull/486)
14
+ * [Include rich_text, attachment, and attachments fields in json partial](https://github.com/rails/jbuilder/pull/459)
15
+
16
+ 2.10.2
17
+ ------
18
+
19
+ * Update scaffold generator to use double quotes, 422 form error responds, and modern string-of-arrays syntax [DHH]
20
+
3
21
  2.10.1
4
- ----------
22
+ ------
5
23
 
6
24
  * Fix keyword arguments warning on Ruby 2.7
7
25
 
8
26
  2.10.0
9
- ----------
27
+ ------
10
28
 
11
29
  * Requires Rails 5+ and Ruby 2.2+
12
30
  * Nested hashes are deep-merged
@@ -13,7 +13,7 @@ Jbuilder is work of [many contributors](https://github.com/rails/jbuilder/graphs
13
13
 
14
14
  #### Fork the Project
15
15
 
16
- Fork the [project on Github](https://github.com/rails/jbuilder) and check out your copy.
16
+ Fork the [project on GitHub](https://github.com/rails/jbuilder) and check out your copy.
17
17
 
18
18
  ```
19
19
  git clone https://github.com/contributor/jbuilder.git
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'jbuilder'
3
- s.version = '2.10.1'
3
+ s.version = '2.11.1'
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'
@@ -50,6 +50,10 @@ module Rails
50
50
 
51
51
  attributes.map { |a| ":#{a}"} * ', '
52
52
  end
53
+
54
+ def virtual_attributes
55
+ attributes.select {|name| name.respond_to?(:virtual?) && name.virtual? }
56
+ end
53
57
  end
54
58
  end
55
59
  end
@@ -4,7 +4,7 @@ require_dependency "<%= namespaced_path %>/application_controller"
4
4
  <% end -%>
5
5
  <% module_namespacing do -%>
6
6
  class <%= controller_class_name %>Controller < ApplicationController
7
- before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
7
+ before_action :set_<%= singular_table_name %>, only: %i[ show update destroy ]
8
8
 
9
9
  # GET <%= route_url %>
10
10
  # GET <%= route_url %>.json
@@ -4,16 +4,14 @@ require_dependency "<%= namespaced_path %>/application_controller"
4
4
  <% end -%>
5
5
  <% module_namespacing do -%>
6
6
  class <%= controller_class_name %>Controller < ApplicationController
7
- before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
7
+ before_action :set_<%= singular_table_name %>, only: %i[ show edit update destroy ]
8
8
 
9
- # GET <%= route_url %>
10
- # GET <%= route_url %>.json
9
+ # GET <%= route_url %> or <%= route_url %>.json
11
10
  def index
12
11
  @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
13
12
  end
14
13
 
15
- # GET <%= route_url %>/1
16
- # GET <%= route_url %>/1.json
14
+ # GET <%= route_url %>/1 or <%= route_url %>/1.json
17
15
  def show
18
16
  end
19
17
 
@@ -26,42 +24,39 @@ class <%= controller_class_name %>Controller < ApplicationController
26
24
  def edit
27
25
  end
28
26
 
29
- # POST <%= route_url %>
30
- # POST <%= route_url %>.json
27
+ # POST <%= route_url %> or <%= route_url %>.json
31
28
  def create
32
29
  @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
33
30
 
34
31
  respond_to do |format|
35
32
  if @<%= orm_instance.save %>
36
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %> }
33
+ format.html { redirect_to @<%= singular_table_name %>, notice: <%= %("#{human_name} was successfully created.") %> }
37
34
  format.json { render :show, status: :created, location: <%= "@#{singular_table_name}" %> }
38
35
  else
39
- format.html { render :new }
36
+ format.html { render :new, status: :unprocessable_entity }
40
37
  format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
41
38
  end
42
39
  end
43
40
  end
44
41
 
45
- # PATCH/PUT <%= route_url %>/1
46
- # PATCH/PUT <%= route_url %>/1.json
42
+ # PATCH/PUT <%= route_url %>/1 or <%= route_url %>/1.json
47
43
  def update
48
44
  respond_to do |format|
49
45
  if @<%= orm_instance.update("#{singular_table_name}_params") %>
50
- format.html { redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %> }
46
+ format.html { redirect_to @<%= singular_table_name %>, notice: <%= %("#{human_name} was successfully updated.") %> }
51
47
  format.json { render :show, status: :ok, location: <%= "@#{singular_table_name}" %> }
52
48
  else
53
- format.html { render :edit }
49
+ format.html { render :edit, status: :unprocessable_entity }
54
50
  format.json { render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity }
55
51
  end
56
52
  end
57
53
  end
58
54
 
59
- # DELETE <%= route_url %>/1
60
- # DELETE <%= route_url %>/1.json
55
+ # DELETE <%= route_url %>/1 or <%= route_url %>/1.json
61
56
  def destroy
62
57
  @<%= orm_instance.destroy %>
63
58
  respond_to do |format|
64
- format.html { redirect_to <%= index_helper %>_url, notice: <%= "'#{human_name} was successfully destroyed.'" %> }
59
+ format.html { redirect_to <%= index_helper %>_url, notice: <%= %("#{human_name} was successfully destroyed.") %> }
65
60
  format.json { head :no_content }
66
61
  end
67
62
  end
@@ -1,2 +1,16 @@
1
1
  json.extract! <%= singular_table_name %>, <%= full_attributes_list %>
2
2
  json.url <%= singular_table_name %>_url(<%= singular_table_name %>, format: :json)
3
+ <%- virtual_attributes.each do |attribute| -%>
4
+ <%- if attribute.type == :rich_text -%>
5
+ json.<%= attribute.name %> <%= singular_table_name %>.<%= attribute.name %>.to_s
6
+ <%- elsif attribute.type == :attachment -%>
7
+ json.<%= attribute.name %> url_for(<%= singular_table_name %>.<%= attribute.name %>)
8
+ <%- elsif attribute.type == :attachments -%>
9
+ json.<%= attribute.name %> do
10
+ json.array!(<%= singular_table_name %>.<%= attribute.name %>) do |<%= attribute.singular_name %>|
11
+ json.id <%= attribute.singular_name %>.id
12
+ json.url url_for(<%= attribute.singular_name %>)
13
+ end
14
+ end
15
+ <%- end -%>
16
+ <%- end -%>
@@ -43,11 +43,11 @@ class Jbuilder
43
43
  # json.age 32
44
44
  # json.person another_jbuilder
45
45
  # { "age": 32, "person": { ... }
46
- value.attributes!
46
+ _format_keys(value.attributes!)
47
47
  else
48
48
  # json.age 32
49
49
  # { "age": 32 }
50
- value
50
+ _format_keys(value)
51
51
  end
52
52
  elsif _is_collection?(value)
53
53
  # json.comments @post.comments, :content, :created_at
@@ -241,8 +241,9 @@ class Jbuilder
241
241
  @attributes
242
242
  end
243
243
 
244
- # Merges hash or array into current builder.
245
- def merge!(hash_or_array)
244
+ # Merges hash, array, or Jbuilder instance into current builder.
245
+ def merge!(object)
246
+ hash_or_array = ::Jbuilder === object ? object.attributes! : object
246
247
  @attributes = _merge_values(@attributes, hash_or_array)
247
248
  end
248
249
 
@@ -272,11 +273,11 @@ class Jbuilder
272
273
  if _blank?(updates)
273
274
  current_value
274
275
  elsif _blank?(current_value) || updates.nil? || current_value.empty? && ::Array === updates
275
- updates
276
+ _format_keys(updates)
276
277
  elsif ::Array === current_value && ::Array === updates
277
- current_value + updates
278
+ current_value + _format_keys(updates)
278
279
  elsif ::Hash === current_value && ::Hash === updates
279
- current_value.deep_merge(updates)
280
+ current_value.deep_merge(_format_keys(updates))
280
281
  else
281
282
  raise MergeError.build(current_value, updates)
282
283
  end
@@ -286,6 +287,16 @@ class Jbuilder
286
287
  @key_formatter ? @key_formatter.format(key) : key.to_s
287
288
  end
288
289
 
290
+ def _format_keys(hash_or_array)
291
+ if ::Array === hash_or_array
292
+ hash_or_array.map { |value| _format_keys(value) }
293
+ elsif ::Hash === hash_or_array
294
+ ::Hash[hash_or_array.collect { |k, v| [_key(k), _format_keys(v)] }]
295
+ else
296
+ hash_or_array
297
+ end
298
+ end
299
+
289
300
  def _set_value(key, value)
290
301
  raise NullError.build(key) if @attributes.nil?
291
302
  raise ArrayError.build(key) if ::Array === @attributes
@@ -43,4 +43,16 @@ class JbuilderGeneratorTest < Rails::Generators::TestCase
43
43
  assert_no_match %r{:created_at, :updated_at}, content
44
44
  end
45
45
  end
46
+
47
+ if Rails::VERSION::MAJOR >= 6
48
+ test 'handles virtual attributes' do
49
+ run_generator %w(Message content:rich_text video:attachment photos:attachments)
50
+
51
+ assert_file 'app/views/messages/_message.json.jbuilder' do |content|
52
+ assert_match %r{json\.content message\.content\.to_s}, content
53
+ assert_match %r{json\.video url_for\(message\.video\)}, content
54
+ assert_match %r{json\.photos do\n json\.array!\(message\.photos\) do \|photo\|\n json\.id photo\.id\n json\.url url_for\(photo\)\n end\nend}, content
55
+ end
56
+ end
57
+ end
46
58
  end
@@ -196,6 +196,18 @@ class JbuilderTest < ActiveSupport::TestCase
196
196
  assert_equal 'Pavel', result['author']['name']
197
197
  end
198
198
 
199
+ test 'support merge! method with Jbuilder instance' do
200
+ obj = jbuild do |json|
201
+ json.foo 'bar'
202
+ end
203
+
204
+ result = jbuild do |json|
205
+ json.merge! obj
206
+ end
207
+
208
+ assert_equal 'bar', result['foo']
209
+ end
210
+
199
211
  test 'blocks are additive via extract syntax' do
200
212
  person = Person.new('Pavel', 27)
201
213
 
@@ -581,6 +593,58 @@ class JbuilderTest < ActiveSupport::TestCase
581
593
  assert_equal ['oats and friends'], result.keys
582
594
  end
583
595
 
596
+ test 'key_format! with merge!' do
597
+ hash = { camel_style: 'for JS' }
598
+ result = jbuild do |json|
599
+ json.key_format! camelize: :lower
600
+ json.merge! hash
601
+ end
602
+
603
+ assert_equal ['camelStyle'], result.keys
604
+ end
605
+
606
+ test 'key_format! with merge! deep' do
607
+ hash = { camel_style: { sub_attr: 'for JS' } }
608
+ result = jbuild do |json|
609
+ json.key_format! camelize: :lower
610
+ json.merge! hash
611
+ end
612
+
613
+ assert_equal ['subAttr'], result['camelStyle'].keys
614
+ end
615
+
616
+ test 'key_format! with set! array of hashes' do
617
+ names = [{ first_name: 'camel', last_name: 'case' }]
618
+ result = jbuild do |json|
619
+ json.key_format! camelize: :lower
620
+ json.set! :names, names
621
+ end
622
+
623
+ assert_equal %w[firstName lastName], result['names'][0].keys
624
+ end
625
+
626
+ test 'key_format! with array! of hashes' do
627
+ names = [{ first_name: 'camel', last_name: 'case' }]
628
+ result = jbuild do |json|
629
+ json.key_format! camelize: :lower
630
+ json.array! names
631
+ end
632
+
633
+ assert_equal %w[firstName lastName], result[0].keys
634
+ end
635
+
636
+ test 'key_format! with merge! array of hashes' do
637
+ names = [{ first_name: 'camel', last_name: 'case' }]
638
+ new_names = [{ first_name: 'snake', last_name: 'case' }]
639
+ result = jbuild do |json|
640
+ json.key_format! camelize: :lower
641
+ json.array! names
642
+ json.merge! new_names
643
+ end
644
+
645
+ assert_equal %w[firstName lastName], result[1].keys
646
+ end
647
+
584
648
  test 'default key_format!' do
585
649
  Jbuilder.key_format camelize: :lower
586
650
  result = jbuild{ |json| json.camel_style 'for JS' }
@@ -55,5 +55,16 @@ if Rails::VERSION::MAJOR > 4
55
55
  assert_match %r{params\.fetch\(:post, \{\}\)}, content
56
56
  end
57
57
  end
58
+
59
+
60
+ if Rails::VERSION::MAJOR >= 6
61
+ test 'handles virtual attributes' do
62
+ run_generator ["Message", "content:rich_text", "video:attachment", "photos:attachments"]
63
+
64
+ assert_file 'app/controllers/messages_controller.rb' do |content|
65
+ assert_match %r{params\.require\(:message\)\.permit\(:content, :video, photos: \[\]\)}, content
66
+ end
67
+ end
68
+ end
58
69
  end
59
70
  end
@@ -31,22 +31,22 @@ 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, notice: "Post was successfully created\." \}}, m
35
35
  assert_match %r{format\.json \{ render :show, status: :created, location: @post \}}, m
36
- assert_match %r{format\.html \{ render :new \}}, m
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, notice: "Post was successfully updated\." \}}, m
42
42
  assert_match %r{format\.json \{ render :show, status: :ok, location: @post \}}, m
43
- assert_match %r{format\.html \{ render :edit \}}, m
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
45
45
  end
46
46
 
47
47
  assert_instance_method :destroy, content do |m|
48
48
  assert_match %r{@post\.destroy}, m
49
- assert_match %r{format\.html \{ redirect_to posts_url, notice: 'Post was successfully destroyed\.' \}}, m
49
+ assert_match %r{format\.html \{ redirect_to posts_url, notice: "Post was successfully destroyed\." \}}, m
50
50
  assert_match %r{format\.json \{ head :no_content \}}, m
51
51
  end
52
52
 
@@ -67,4 +67,14 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
67
67
  assert_match %r{params\.fetch\(:post, \{\}\)}, content
68
68
  end
69
69
  end
70
+
71
+ if Rails::VERSION::MAJOR >= 6
72
+ test 'handles virtual attributes' do
73
+ run_generator %w(Message content:rich_text video:attachment photos:attachments)
74
+
75
+ assert_file 'app/controllers/messages_controller.rb' do |content|
76
+ assert_match %r{params\.require\(:message\)\.permit\(:content, :video, photos: \[\]\)}, content
77
+ end
78
+ end
79
+ end
70
80
  end
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.10.1
4
+ version: 2.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-12 00:00:00.000000000 Z
11
+ date: 2021-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.0.0
27
- description:
27
+ description:
28
28
  email: david@basecamp.com
29
29
  executables: []
30
30
  extensions: []
@@ -71,7 +71,7 @@ homepage: https://github.com/rails/jbuilder
71
71
  licenses:
72
72
  - MIT
73
73
  metadata: {}
74
- post_install_message:
74
+ post_install_message:
75
75
  rdoc_options: []
76
76
  require_paths:
77
77
  - lib
@@ -87,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
87
  version: '0'
88
88
  requirements: []
89
89
  rubygems_version: 3.1.2
90
- signing_key:
90
+ signing_key:
91
91
  specification_version: 4
92
92
  summary: Create JSON structures via a Builder-style DSL
93
93
  test_files: