blueprinter 0.20.0 → 0.21.0

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: 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