blueprinter 0.20.0 → 0.21.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 +4 -4
- data/CHANGELOG.md +4 -1
- data/README.md +36 -1
- data/lib/blueprinter/base.rb +10 -7
- data/lib/blueprinter/empty_types.rb +25 -0
- data/lib/blueprinter/extractor.rb +1 -1
- data/lib/blueprinter/extractors/association_extractor.rb +4 -2
- data/lib/blueprinter/extractors/auto_extractor.rb +3 -1
- data/lib/blueprinter/field.rb +4 -4
- data/lib/blueprinter/helpers/base_helpers.rb +2 -9
- data/lib/blueprinter/helpers/type_helpers.rb +13 -0
- data/lib/blueprinter/transformer.rb +3 -3
- data/lib/blueprinter/version.rb +1 -1
- data/lib/blueprinter/view.rb +3 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8c9a52221d1a5473708cc7391865c25400d9e34440a1c0c52d76f2e7c811997
|
4
|
+
data.tar.gz: 380008b99bfd079c13d3c8ce019e4160b92141c20c639b233adaa6ef1ccfc9e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 225d6b77da9cf47411b014372234e7091d52d6a8ce0d358cc01d6f4a9eb188eafab70a50295a9e9ba3b15863d91cc35a3e3dcdcf501221ca8c959c785420e064
|
7
|
+
data.tar.gz: 0f407b0d11bcce8176c8e31f15e16f497431ffffe637ffe35e03779e91335902d70ef778546f55913b18885a261a9472fadc81b62caef490e64eb02d07900f5f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
## 0.21.0 - 2019/12/19
|
2
|
+
* 🚀 [FEATURE] Ability to specify `default_if` field/association option for more control on when the default value is applied. [191](https://github.com/procore/blueprinter/pull/191). Thanks to [@mcclayton](https://github.com/mcclayton).
|
3
|
+
|
1
4
|
## 0.20.0 - 2019/10/15
|
2
5
|
* 🚀 [FEATURE] Ability to include multiple views in a single method call with `include_views`. [184](https://github.com/procore/blueprinter/pull/184). Thanks to [@narendranvelmurugan](https://github.com/narendranvelmurugan).
|
3
6
|
|
@@ -42,7 +45,7 @@
|
|
42
45
|
|
43
46
|
## 0.12.1 - 2019/1/24
|
44
47
|
|
45
|
-
* 🐛 [BUGFIX] Fix boolean `false` values getting serialized as `null`. Please see PR [#132](https://github.com/procore/blueprinter/pull/132).
|
48
|
+
* 🐛 [BUGFIX] Fix boolean `false` values getting serialized as `null`. Please see PR [#132](https://github.com/procore/blueprinter/pull/132). Thanks to [@samsongz](https://github.com/samsongz).
|
46
49
|
|
47
50
|
## 0.12.0 - 2019/1/16
|
48
51
|
|
data/README.md
CHANGED
@@ -374,7 +374,7 @@ Blueprinter.configure do |config|
|
|
374
374
|
end
|
375
375
|
```
|
376
376
|
|
377
|
-
#### Field-level/
|
377
|
+
#### Field-level/Association-level Setting
|
378
378
|
```ruby
|
379
379
|
class UserBlueprint < Blueprinter::Base
|
380
380
|
identifier :uuid
|
@@ -390,6 +390,41 @@ end
|
|
390
390
|
</details>
|
391
391
|
|
392
392
|
|
393
|
+
<details>
|
394
|
+
<summary>default_if</summary>
|
395
|
+
|
396
|
+
---
|
397
|
+
|
398
|
+
Sometimes, you may want certain "empty" values to pass through to the default value.
|
399
|
+
Blueprinter provides the ability to treat the following empty types as the default value (or `nil` if no default provided).
|
400
|
+
|
401
|
+
#### Blueprinter::EMPTY_COLLECTION
|
402
|
+
An empty array or empty active record collection.
|
403
|
+
|
404
|
+
#### Blueprinter::EMPTY_HASH
|
405
|
+
An empty hash.
|
406
|
+
|
407
|
+
#### Blueprinter::EMPTY_STRING
|
408
|
+
An empty string or symbol.
|
409
|
+
|
410
|
+
#### Field-level/Association-level Setting
|
411
|
+
```ruby
|
412
|
+
class UserBlueprint < Blueprinter::Base
|
413
|
+
identifier :uuid
|
414
|
+
|
415
|
+
view :normal do
|
416
|
+
# If first_name is an empty string, it will become "N/A"
|
417
|
+
field :first_name, default_if: Blueprinter::EmptyString, default: "N/A"
|
418
|
+
# If the projects association collection is empty, it will become nil
|
419
|
+
association :projects, blueprint: ProjectBlueprint, default_if: Blueprinter::EmptyCollection
|
420
|
+
end
|
421
|
+
end
|
422
|
+
```
|
423
|
+
|
424
|
+
---
|
425
|
+
</details>
|
426
|
+
|
427
|
+
|
393
428
|
<details>
|
394
429
|
<summary>Supporting Dynamic Blueprints For Associations</summary>
|
395
430
|
|
data/lib/blueprinter/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'blueprinter_error'
|
2
2
|
require_relative 'configuration'
|
3
|
+
require_relative 'empty_types'
|
3
4
|
require_relative 'extractor'
|
4
5
|
require_relative 'extractors/association_extractor'
|
5
6
|
require_relative 'extractors/auto_extractor'
|
@@ -8,6 +9,7 @@ require_relative 'extractors/hash_extractor'
|
|
8
9
|
require_relative 'extractors/public_send_extractor'
|
9
10
|
require_relative 'formatters/date_time_formatter'
|
10
11
|
require_relative 'field'
|
12
|
+
require_relative 'helpers/type_helpers'
|
11
13
|
require_relative 'helpers/base_helpers'
|
12
14
|
require_relative 'view'
|
13
15
|
require_relative 'view_collection'
|
@@ -252,6 +254,7 @@ module Blueprinter
|
|
252
254
|
unless view_collection.has_view? view_name
|
253
255
|
raise BlueprinterError, "View '#{view_name}' is not defined"
|
254
256
|
end
|
257
|
+
|
255
258
|
data = prepare_data(object, view_name, local_options)
|
256
259
|
prepend_root_and_meta(data, root, meta)
|
257
260
|
end
|
@@ -283,9 +286,9 @@ module Blueprinter
|
|
283
286
|
# @param class name [Class] which implements the method transform to include for
|
284
287
|
# serialization.
|
285
288
|
#
|
286
|
-
#
|
289
|
+
#
|
287
290
|
# @example Specifying a DynamicFieldTransformer transformer for including dynamic fields to be serialized.
|
288
|
-
# class User
|
291
|
+
# class User
|
289
292
|
# def custom_columns
|
290
293
|
# self.dynamic_fields # which is an array of some columns
|
291
294
|
# end
|
@@ -297,7 +300,7 @@ module Blueprinter
|
|
297
300
|
#
|
298
301
|
# class UserBlueprint < Blueprinter::Base
|
299
302
|
# fields :first_name, :last_name
|
300
|
-
# transform DynamicFieldTransformer
|
303
|
+
# transform DynamicFieldTransformer
|
301
304
|
# # other code
|
302
305
|
# end
|
303
306
|
#
|
@@ -346,9 +349,9 @@ module Blueprinter
|
|
346
349
|
# view :normal do
|
347
350
|
# fields :first_name, :last_name
|
348
351
|
# end
|
349
|
-
# view :special do
|
352
|
+
# view :special do
|
350
353
|
# fields :birthday, :company
|
351
|
-
# end
|
354
|
+
# end
|
352
355
|
# view :extended do
|
353
356
|
# include_views :normal, :special # include fields specified from above.
|
354
357
|
# field :description
|
@@ -360,8 +363,8 @@ module Blueprinter
|
|
360
363
|
|
361
364
|
|
362
365
|
def self.include_views(*view_names)
|
363
|
-
|
364
|
-
end
|
366
|
+
current_view.include_views(view_names)
|
367
|
+
end
|
365
368
|
|
366
369
|
|
367
370
|
# Exclude a field that was mixed into the current view.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'helpers/type_helpers'
|
2
|
+
|
3
|
+
module Blueprinter
|
4
|
+
EMPTY_COLLECTION = "empty_collection".freeze
|
5
|
+
EMPTY_HASH = "empty_hash".freeze
|
6
|
+
EMPTY_STRING = "empty_string".freeze
|
7
|
+
|
8
|
+
module EmptyTypes
|
9
|
+
include TypeHelpers
|
10
|
+
private
|
11
|
+
|
12
|
+
def use_default_value?(value, empty_type)
|
13
|
+
case empty_type
|
14
|
+
when Blueprinter::EMPTY_COLLECTION
|
15
|
+
array_like?(value) && value.empty?
|
16
|
+
when Blueprinter::EMPTY_HASH
|
17
|
+
value.is_a?(Hash) && value.empty?
|
18
|
+
when Blueprinter::EMPTY_STRING
|
19
|
+
value.to_s == ""
|
20
|
+
else
|
21
|
+
value.nil?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module Blueprinter
|
2
2
|
# @api private
|
3
3
|
class AssociationExtractor < Extractor
|
4
|
+
include EmptyTypes
|
5
|
+
|
4
6
|
def initialize
|
5
7
|
@extractor = AutoExtractor.new
|
6
8
|
end
|
7
9
|
|
8
10
|
def extract(association_name, object, local_options, options={})
|
9
|
-
options_without_default = options.reject { |k,_| k == :default }
|
11
|
+
options_without_default = options.reject { |k,_| k == :default || k == :default_if }
|
10
12
|
value = @extractor.extract(association_name, object, local_options, options_without_default)
|
11
|
-
return default_value(options) if value
|
13
|
+
return default_value(options) if use_default_value?(value, options[:default_if])
|
12
14
|
view = options[:view] || :default
|
13
15
|
blueprint = association_blueprint(options[:blueprint], value)
|
14
16
|
blueprint.prepare(value, view_name: view, local_options: local_options)
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Blueprinter
|
2
2
|
# @api private
|
3
3
|
class AutoExtractor < Extractor
|
4
|
+
include EmptyTypes
|
5
|
+
|
4
6
|
def initialize
|
5
7
|
@hash_extractor = HashExtractor.new
|
6
8
|
@public_send_extractor = PublicSendExtractor.new
|
@@ -11,7 +13,7 @@ module Blueprinter
|
|
11
13
|
def extract(field_name, object, local_options, options = {})
|
12
14
|
extraction = extractor(object, options).extract(field_name, object, local_options, options)
|
13
15
|
value = @datetime_formatter.format(extraction, options)
|
14
|
-
value
|
16
|
+
use_default_value?(value, options[:default_if]) ? default_value(options) : value
|
15
17
|
end
|
16
18
|
|
17
19
|
private
|
data/lib/blueprinter/field.rb
CHANGED
@@ -46,10 +46,10 @@ class Blueprinter::Field
|
|
46
46
|
|
47
47
|
# Use field-level callable, or when not defined, try global callable
|
48
48
|
tmp = if options.key?(condition)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
options.fetch(condition)
|
50
|
+
elsif config.valid_callable?(condition)
|
51
|
+
config.public_send(condition)
|
52
|
+
end
|
53
53
|
|
54
54
|
return false unless tmp
|
55
55
|
|
@@ -5,12 +5,9 @@ module Blueprinter
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module SingletonMethods
|
8
|
-
|
9
|
-
def active_record_relation?(object)
|
10
|
-
!!(defined?(ActiveRecord::Relation) &&
|
11
|
-
object.is_a?(ActiveRecord::Relation))
|
12
|
-
end
|
8
|
+
include TypeHelpers
|
13
9
|
|
10
|
+
private
|
14
11
|
def prepare_for_render(object, options)
|
15
12
|
view_name = options.delete(:view) || :default
|
16
13
|
root = options.delete(:root)
|
@@ -77,10 +74,6 @@ module Blueprinter
|
|
77
74
|
@view_collection ||= ViewCollection.new
|
78
75
|
end
|
79
76
|
|
80
|
-
def array_like?(object)
|
81
|
-
object.is_a?(Array) || active_record_relation?(object)
|
82
|
-
end
|
83
|
-
|
84
77
|
def associations(view_name = :default)
|
85
78
|
view_collection.fields_for(view_name).select { |f| f.options[:association] }
|
86
79
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Blueprinter
|
2
|
+
module TypeHelpers
|
3
|
+
private
|
4
|
+
def active_record_relation?(object)
|
5
|
+
!!(defined?(ActiveRecord::Relation) &&
|
6
|
+
object.is_a?(ActiveRecord::Relation))
|
7
|
+
end
|
8
|
+
|
9
|
+
def array_like?(object)
|
10
|
+
object.is_a?(Array) || active_record_relation?(object)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Blueprinter
|
2
2
|
# @api private
|
3
3
|
class Transformer
|
4
|
-
def transform(
|
4
|
+
def transform(_result_hash, _primary_obj, _options = {})
|
5
5
|
fail NotImplementedError, "A Transformer must implement #transform"
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.transform(result_hash,primary_obj, options={})
|
9
|
-
self.new.transform(result_hash,primary_obj, options)
|
8
|
+
def self.transform(result_hash, primary_obj, options = {})
|
9
|
+
self.new.transform(result_hash, primary_obj, options)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/blueprinter/version.rb
CHANGED
data/lib/blueprinter/view.rb
CHANGED
@@ -23,7 +23,7 @@ module Blueprinter
|
|
23
23
|
view.excluded_field_names.each do |field_name|
|
24
24
|
exclude_field(field_name)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
view.transformers.each do |transformer|
|
28
28
|
self.add_transformer(transformer)
|
29
29
|
end
|
@@ -37,12 +37,12 @@ module Blueprinter
|
|
37
37
|
view_names.each do |view_name|
|
38
38
|
included_view_names << view_name
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
41
41
|
|
42
42
|
def exclude_field(field_name)
|
43
43
|
excluded_field_names << field_name
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def exclude_fields(field_names)
|
47
47
|
field_names.each do |field_name|
|
48
48
|
excluded_field_names << field_name
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blueprinter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Hess
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-12-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: factory_bot
|
@@ -169,6 +169,7 @@ files:
|
|
169
169
|
- lib/blueprinter/base.rb
|
170
170
|
- lib/blueprinter/blueprinter_error.rb
|
171
171
|
- lib/blueprinter/configuration.rb
|
172
|
+
- lib/blueprinter/empty_types.rb
|
172
173
|
- lib/blueprinter/extractor.rb
|
173
174
|
- lib/blueprinter/extractors/association_extractor.rb
|
174
175
|
- lib/blueprinter/extractors/auto_extractor.rb
|
@@ -178,6 +179,7 @@ files:
|
|
178
179
|
- lib/blueprinter/field.rb
|
179
180
|
- lib/blueprinter/formatters/date_time_formatter.rb
|
180
181
|
- lib/blueprinter/helpers/base_helpers.rb
|
182
|
+
- lib/blueprinter/helpers/type_helpers.rb
|
181
183
|
- lib/blueprinter/transformer.rb
|
182
184
|
- lib/blueprinter/version.rb
|
183
185
|
- lib/blueprinter/view.rb
|