1
+ # frozen_string_literal: true
2
+
1
3
require 'active_support'
2
4
require 'jbuilder/jbuilder'
3
5
require 'jbuilder/blank'
@@ -12,14 +14,18 @@ class Jbuilder
12
14
@@ignore_nil = false
13
15
@@deep_format_keys = false
14
16
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
+ )
16
23
@attributes = { }
24
+ @key_formatter = key_formatter
25
+ @ignore_nil = ignore_nil
26
+ @deep_format_keys = deep_format_keys
17
27
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
23
29
end
24
30
25
31
# Yields a builder and automatically turns the result into a JSON string
@@ -58,20 +64,12 @@ def set!(key, value = BLANK, *args, &block)
58
64
else
59
65
# json.author @post.creator, :name, :email_address
60
66
# { "author": { "name": "David", "email_address": "david@loudthinking.com" } }
61
- _merge_block ( key ) { extract! value , * args }
67
+ _merge_block ( key ) { _extract value , args }
62
68
end
63
69
64
70
_set_value key , result
65
71
end
66
72
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
-
75
73
# Specifies formatting to be applied to the key. Passing in a name of a function
76
74
# will cause that function to be called on the key. So :upcase will upper case
77
75
# the key. You can also pass in lambdas for more complex transformations.
@@ -100,13 +98,13 @@ def method_missing(*args, &block)
100
98
#
101
99
# { "_first_name": "David" }
102
100
#
103
- def key_format! ( * args )
104
- @key_formatter = KeyFormatter . new ( * args )
101
+ def key_format! ( ... )
102
+ @key_formatter = KeyFormatter . new ( ... )
105
103
end
106
104
107
105
# 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 ( ... )
110
108
end
111
109
112
110
# If you want to skip adding nil values to your JSON hash. This is useful
@@ -215,7 +213,7 @@ def array!(collection = [], *attributes, &block)
215
213
elsif ::Kernel . block_given?
216
214
_map_collection ( collection , &block )
217
215
elsif attributes . any?
218
- _map_collection ( collection ) { |element | extract! element , * attributes }
216
+ _map_collection ( collection ) { |element | _extract element , attributes }
219
217
else
220
218
_format_keys ( collection . to_a )
221
219
end
@@ -241,18 +239,14 @@ def array!(collection = [], *attributes, &block)
241
239
#
242
240
# json.(@person, :name, :age)
243
241
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
249
243
end
250
244
251
245
def call ( object , *attributes , &block )
252
246
if ::Kernel . block_given?
253
247
array! object , &block
254
248
else
255
- extract! object , * attributes
249
+ _extract object , attributes
256
250
end
257
251
end
258
252
@@ -281,6 +275,16 @@ def target!
281
275
282
276
private
283
277
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
+
284
288
def _extract_hash_values ( object , attributes )
285
289
attributes . each { |key | _set_value key , _format_keys ( object . fetch ( key ) ) }
286
290
end
@@ -311,7 +315,13 @@ def _merge_values(current_value, updates)
311
315
end
312
316
313
317
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
315
325
end
316
326
317
327
def _format_keys ( hash_or_array )
@@ -350,16 +360,12 @@ def _scope
350
360
end
351
361
352
362
def _is_collection? ( object )
353
- _object_respond_to? ( object , :map , :count ) && !( ::Struct === object )
363
+ object . respond_to? ( :map ) && object . respond_to? ( :count ) && !( ::Struct === object )
354
364
end
355
365
356
366
def _blank? ( value = @attributes )
357
367
BLANK == value
358
368
end
359
-
360
- def _object_respond_to? ( object , *methods )
361
- methods . all? { |m | object . respond_to? ( m ) }
362
- end
363
369
end
364
370
365
371
require 'jbuilder/railtie' if defined? ( Rails )
0 commit comments