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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf9b763f4f3719ba9e005676312f09f21165d8bc53ede0ee5ac0d171fcbae828
4
- data.tar.gz: 2984aa6879ecafa6e15e49a95edc0b3fdad19d0f3ef0cdb51c484a7785b05303
3
+ metadata.gz: c8c9a52221d1a5473708cc7391865c25400d9e34440a1c0c52d76f2e7c811997
4
+ data.tar.gz: 380008b99bfd079c13d3c8ce019e4160b92141c20c639b233adaa6ef1ccfc9e5
5
5
  SHA512:
6
- metadata.gz: 8141264e23abc76304a7dc22527880e22c82b1dbb796e4b4f9f5cbd6bd3a0b95c029aa83f3d68b557c530904b0131b19338fde99b00693374b95f529d6424027
7
- data.tar.gz: 74c36b42fdb6655084572d94c7cb8ac610855c587604c3aae4c093590fb0254641de043a1b58d25ed2c963db42209d85444fdcdd8370189d766228136804b37d
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/Associaion-level Setting
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
 
@@ -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
- current_view.include_views(view_names)
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,6 +1,6 @@
1
1
  module Blueprinter
2
2
  class Extractor
3
- def extract(field_name, object, local_options, options={})
3
+ def extract(_field_name, _object, _local_options, _options={})
4
4
  fail NotImplementedError, "An Extractor must implement #extract"
5
5
  end
6
6
 
@@ -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.nil?
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.nil? ? default_value(options) : value
16
+ use_default_value?(value, options[:default_if]) ? default_value(options) : value
15
17
  end
16
18
 
17
19
  private
@@ -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
- options.fetch(condition)
50
- elsif config.valid_callable?(condition)
51
- config.public_send(condition)
52
- end
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
- private
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(result_hash,primary_obj, options={})
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
@@ -1,3 +1,3 @@
1
1
  module Blueprinter
2
- VERSION = '0.20.0'
2
+ VERSION = '0.21.0'.freeze
3
3
  end
@@ -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.20.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-10-16 00:00:00.000000000 Z
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