Skip to content

Commit 1245776

Browse files
authored
Merge branch 'main' into moberegger/optimize_options_merges
2 parents 9ca4d05 + f966bbf commit 1245776

21 files changed

+281
-352
lines changed

Appraisals

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
appraise "rails-7-0" do
24
gem "rails", "~> 7.0.0"
35
gem "concurrent-ruby", "< 1.3.5" # to avoid problem described in https://github.com/rails/rails/pull/54264

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
source "https://rubygems.org"
24

35
gemspec

Rakefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require "bundler/setup"
24
require "bundler/gem_tasks"
35
require "rake/testtask"

jbuilder.gemspec

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require_relative "lib/jbuilder/version"
24

35
Gem::Specification.new do |s|
@@ -9,10 +11,10 @@ Gem::Specification.new do |s|
911
s.homepage = 'https://github.com/rails/jbuilder'
1012
s.license = 'MIT'
1113

12-
s.required_ruby_version = '>= 2.2.2'
14+
s.required_ruby_version = '>= 3.0.0'
1315

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

1719
if RUBY_ENGINE == 'rbx'
1820
s.add_development_dependency('racc')

lib/generators/rails/jbuilder_generator.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require 'rails/generators/named_base'
24
require 'rails/generators/resource_helpers'
35

lib/generators/rails/scaffold_controller_generator.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require 'rails/generators'
24
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
35

lib/jbuilder.rb

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require 'active_support'
24
require 'jbuilder/jbuilder'
35
require 'jbuilder/blank'
@@ -12,14 +14,18 @@ class Jbuilder
1214
@@ignore_nil = false
1315
@@deep_format_keys = false
1416

15-
def initialize(options = {})
17+
def initialize(
18+
key_formatter: @@key_formatter,
19+
ignore_nil: @@ignore_nil,
20+
deep_format_keys: @@deep_format_keys,
21+
&block
22+
)
1623
@attributes = {}
24+
@key_formatter = key_formatter
25+
@ignore_nil = ignore_nil
26+
@deep_format_keys = deep_format_keys
1727

18-
@key_formatter = options.fetch(:key_formatter){ @@key_formatter ? @@key_formatter.clone : nil}
19-
@ignore_nil = options.fetch(:ignore_nil, @@ignore_nil)
20-
@deep_format_keys = options.fetch(:deep_format_keys, @@deep_format_keys)
21-
22-
yield self if ::Kernel.block_given?
28+
yield self if block
2329
end
2430

2531
# Yields a builder and automatically turns the result into a JSON string
@@ -58,20 +64,12 @@ def set!(key, value = BLANK, *args, &block)
5864
else
5965
# json.author @post.creator, :name, :email_address
6066
# { "author": { "name": "David", "email_address": "david@loudthinking.com" } }
61-
_merge_block(key){ extract! value, *args }
67+
_merge_block(key){ _extract value, args }
6268
end
6369

6470
_set_value key, result
6571
end
6672

67-
def method_missing(*args, &block)
68-
if ::Kernel.block_given?
69-
set!(*args, &block)
70-
else
71-
set!(*args)
72-
end
73-
end
74-
7573
# Specifies formatting to be applied to the key. Passing in a name of a function
7674
# will cause that function to be called on the key. So :upcase will upper case
7775
# the key. You can also pass in lambdas for more complex transformations.
@@ -100,13 +98,13 @@ def method_missing(*args, &block)
10098
#
10199
# { "_first_name": "David" }
102100
#
103-
def key_format!(*args)
104-
@key_formatter = KeyFormatter.new(*args)
101+
def key_format!(...)
102+
@key_formatter = KeyFormatter.new(...)
105103
end
106104

107105
# Same as the instance method key_format! except sets the default.
108-
def self.key_format(*args)
109-
@@key_formatter = KeyFormatter.new(*args)
106+
def self.key_format(...)
107+
@@key_formatter = KeyFormatter.new(...)
110108
end
111109

112110
# If you want to skip adding nil values to your JSON hash. This is useful
@@ -215,7 +213,7 @@ def array!(collection = [], *attributes, &block)
215213
elsif ::Kernel.block_given?
216214
_map_collection(collection, &block)
217215
elsif attributes.any?
218-
_map_collection(collection) { |element| extract! element, *attributes }
216+
_map_collection(collection) { |element| _extract element, attributes }
219217
else
220218
_format_keys(collection.to_a)
221219
end
@@ -241,18 +239,14 @@ def array!(collection = [], *attributes, &block)
241239
#
242240
# json.(@person, :name, :age)
243241
def extract!(object, *attributes)
244-
if ::Hash === object
245-
_extract_hash_values(object, attributes)
246-
else
247-
_extract_method_values(object, attributes)
248-
end
242+
_extract object, attributes
249243
end
250244

251245
def call(object, *attributes, &block)
252246
if ::Kernel.block_given?
253247
array! object, &block
254248
else
255-
extract! object, *attributes
249+
_extract object, attributes
256250
end
257251
end
258252

@@ -281,6 +275,16 @@ def target!
281275

282276
private
283277

278+
alias_method :method_missing, :set!
279+
280+
def _extract(object, attributes)
281+
if ::Hash === object
282+
_extract_hash_values(object, attributes)
283+
else
284+
_extract_method_values(object, attributes)
285+
end
286+
end
287+
284288
def _extract_hash_values(object, attributes)
285289
attributes.each{ |key| _set_value key, _format_keys(object.fetch(key)) }
286290
end
@@ -311,7 +315,13 @@ def _merge_values(current_value, updates)
311315
end
312316

313317
def _key(key)
314-
@key_formatter ? @key_formatter.format(key) : key.to_s
318+
if @key_formatter
319+
@key_formatter.format(key)
320+
elsif key.is_a?(::Symbol)
321+
key.name
322+
else
323+
key.to_s
324+
end
315325
end
316326

317327
def _format_keys(hash_or_array)
@@ -350,16 +360,12 @@ def _scope
350360
end
351361

352362
def _is_collection?(object)
353-
_object_respond_to?(object, :map, :count) && !(::Struct === object)
363+
object.respond_to?(:map) && object.respond_to?(:count) && !(::Struct === object)
354364
end
355365

356366
def _blank?(value=@attributes)
357367
BLANK == value
358368
end
359-
360-
def _object_respond_to?(object, *methods)
361-
methods.all?{ |m| object.respond_to?(m) }
362-
end
363369
end
364370

365371
require 'jbuilder/railtie' if defined?(Rails)

lib/jbuilder/blank.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
class Jbuilder
24
class Blank
35
def ==(other)

lib/jbuilder/collection_renderer.rb

Lines changed: 19 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,11 @@
1+
# frozen_string_literal: true
2+
13
require 'delegate'
2-
require 'active_support/concern'
34
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'
106

117
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:
359
class ScopedIterator < ::SimpleDelegator # :nodoc:
3610
include Enumerable
3711

@@ -40,16 +14,6 @@ def initialize(obj, scope)
4014
@scope = scope
4115
end
4216

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:
5317
def each_with_info
5418
return enum_for(:each_with_info) unless block_given?
5519

@@ -60,51 +24,29 @@ def each_with_info
6024
end
6125

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

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
7931
end
80-
else
81-
# Rails 6.0 support:
82-
class CollectionRenderer < ::ActionView::PartialRenderer # :nodoc:
83-
include CollectionRenderable
8432

85-
def initialize(lookup_context, options, &scope)
86-
super(lookup_context)
87-
@options = options
88-
@scope = scope
89-
end
33+
private
9034

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)
9337
end
9438

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
10142

102-
def collection_with_template(view, template)
103-
@collection = ScopedIterator.new(@collection, @scope)
43+
def json
44+
@options[:locals].fetch(:json)
45+
end
10446

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
10850
end
10951

11052
class EnumerableCompat < ::SimpleDelegator

lib/jbuilder/errors.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require 'jbuilder/jbuilder'
24

35
class Jbuilder

0 commit comments

Comments
 (0)