blueprinter-rb 1.1.1 → 1.1.2

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.
@@ -60,7 +60,7 @@ module Blueprinter
60
60
  name,
61
61
  extractor,
62
62
  self,
63
- block: block,
63
+ block: block
64
64
  )
65
65
  end
66
66
 
@@ -125,7 +125,7 @@ module Blueprinter
125
125
  options.fetch(:name) { method },
126
126
  options.fetch(:extractor) { Blueprinter.configuration.extractor_default.new },
127
127
  self,
128
- options.merge(block: block),
128
+ options.merge(block: block)
129
129
  )
130
130
  end
131
131
 
@@ -165,7 +165,7 @@ module Blueprinter
165
165
  method,
166
166
  options.merge(
167
167
  association: true,
168
- extractor: options.fetch(:extractor) { AssociationExtractor.new },
168
+ extractor: options.fetch(:extractor) { AssociationExtractor.new }
169
169
  ),
170
170
  &block
171
171
  )
@@ -254,9 +254,7 @@ module Blueprinter
254
254
  #
255
255
  # @api private
256
256
  def self.prepare(object, view_name:, local_options:, root: nil, meta: nil)
257
- unless view_collection.has_view? view_name
258
- raise BlueprinterError, "View '#{view_name}' is not defined"
259
- end
257
+ raise BlueprinterError, "View '#{view_name}' is not defined" unless view_collection.view? view_name
260
258
 
261
259
  data = prepare_data(object, view_name, local_options)
262
260
  prepend_root_and_meta(data, root, meta)
@@ -281,7 +279,6 @@ module Blueprinter
281
279
  end
282
280
  end
283
281
 
284
-
285
282
  # Specify one transformer to be included for serialization.
286
283
  # Takes a class which extends Blueprinter::Transformer
287
284
  #
@@ -317,7 +314,6 @@ module Blueprinter
317
314
  current_view.add_transformer(transformer)
318
315
  end
319
316
 
320
-
321
317
  # Specify another view that should be mixed into the current view.
322
318
  #
323
319
  # @param view_name [Symbol] the view to mix into the current view.
@@ -340,7 +336,6 @@ module Blueprinter
340
336
  current_view.include_view(view_name)
341
337
  end
342
338
 
343
-
344
339
  # Specify additional views that should be mixed into the current view.
345
340
  #
346
341
  # @param view_name [Array<Symbol>] the views to mix into the current view.
@@ -363,12 +358,10 @@ module Blueprinter
363
358
  #
364
359
  # @return [Array<Symbol>] an array of view names.
365
360
 
366
-
367
361
  def self.include_views(*view_names)
368
362
  current_view.include_views(view_names)
369
363
  end
370
364
 
371
-
372
365
  # Exclude a field that was mixed into the current view.
373
366
  #
374
367
  # @param field_name [Symbol] the field to exclude from the current view.
@@ -446,13 +439,13 @@ module Blueprinter
446
439
  # end
447
440
  # end
448
441
  #
449
- # ExampleBlueprint.has_view?(:custom) => true
450
- # ExampleBlueprint.has_view?(:doesnt_exist) => false
442
+ # ExampleBlueprint.view?(:custom) => true
443
+ # ExampleBlueprint.view?(:doesnt_exist) => false
451
444
  #
452
445
  # @return [Boolean] a boolean value indicating if the view is
453
446
  # supported by this Blueprint.
454
- def self.has_view?(view_name)
455
- view_collection.has_view? view_name
447
+ def self.view?(view_name)
448
+ view_collection.view? view_name
456
449
  end
457
450
  end
458
451
  end
@@ -2,9 +2,10 @@
2
2
 
3
3
  module Blueprinter
4
4
  class Configuration
5
- attr_accessor :association_default, :datetime_format, :deprecations, :field_default, :generator, :if, :method, :sort_fields_by, :unless, :extractor_default, :default_transformers, :custom_array_like_classes
5
+ attr_accessor :association_default, :datetime_format, :deprecations, :field_default, :generator, :if, :method,
6
+ :sort_fields_by, :unless, :extractor_default, :default_transformers, :custom_array_like_classes
6
7
 
7
- VALID_CALLABLES = %i(if unless).freeze
8
+ VALID_CALLABLES = %i[if unless].freeze
8
9
 
9
10
  def initialize
10
11
  @deprecations = :stderror
@@ -4,8 +4,8 @@
4
4
  module Blueprinter
5
5
  class Deprecation
6
6
  class << self
7
- VALID_BEHAVIORS = %i(silence stderror raise).freeze
8
- MESSAGE_PREFIX = "[DEPRECATION::WARNING] Blueprinter:"
7
+ VALID_BEHAVIORS = %i[silence stderror raise].freeze
8
+ MESSAGE_PREFIX = '[DEPRECATION::WARNING] Blueprinter:'
9
9
 
10
10
  def report(message)
11
11
  full_msg = qualified_message(message)
@@ -28,7 +28,7 @@ module Blueprinter
28
28
 
29
29
  def behavior
30
30
  configured = Blueprinter.configuration.deprecations
31
- return configured unless !VALID_BEHAVIORS.include?(configured)
31
+ return configured if VALID_BEHAVIORS.include?(configured)
32
32
 
33
33
  :stderror
34
34
  end
@@ -3,12 +3,13 @@
3
3
  require_relative 'helpers/type_helpers'
4
4
 
5
5
  module Blueprinter
6
- EMPTY_COLLECTION = "empty_collection"
7
- EMPTY_HASH = "empty_hash"
8
- EMPTY_STRING = "empty_string"
6
+ EMPTY_COLLECTION = 'empty_collection'
7
+ EMPTY_HASH = 'empty_hash'
8
+ EMPTY_STRING = 'empty_string'
9
9
 
10
10
  module EmptyTypes
11
11
  include TypeHelpers
12
+
12
13
  private
13
14
 
14
15
  def use_default_value?(value, empty_type)
@@ -20,11 +21,11 @@ module Blueprinter
20
21
  when Blueprinter::EMPTY_HASH
21
22
  value.is_a?(Hash) && value.empty?
22
23
  when Blueprinter::EMPTY_STRING
23
- value.to_s == ""
24
+ value.to_s == ''
24
25
  else
25
26
  Blueprinter::Deprecation.report(
26
- "Invalid empty type '#{empty_type}' received. Blueprinter will raise an error in the next major version."\
27
- "Must be one of [nil, Blueprinter::EMPTY_COLLECTION, Blueprinter::EMPTY_HASH, Blueprinter::EMPTY_STRING]"
27
+ "Invalid empty type '#{empty_type}' received. Blueprinter will raise an error in the next major version." \
28
+ 'Must be one of [nil, Blueprinter::EMPTY_COLLECTION, Blueprinter::EMPTY_HASH, Blueprinter::EMPTY_STRING]'
28
29
  )
29
30
  end
30
31
  end
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Blueprinter
4
4
  class Extractor
5
- def extract(_field_name, _object, _local_options, _options={})
6
- fail NotImplementedError, "An Extractor must implement #extract"
5
+ def extract(_field_name, _object, _local_options, _options = {})
6
+ raise NotImplementedError, 'An Extractor must implement #extract'
7
7
  end
8
8
 
9
- def self.extract(field_name, object, local_options, options={})
10
- self.new.extract(field_name, object, local_options, options)
9
+ def self.extract(field_name, object, local_options, options = {})
10
+ new.extract(field_name, object, local_options, options)
11
11
  end
12
12
  end
13
13
  end
@@ -9,12 +9,13 @@ module Blueprinter
9
9
  @extractor = Blueprinter.configuration.extractor_default.new
10
10
  end
11
11
 
12
- def extract(association_name, object, local_options, options={})
13
- options_without_default = options.reject { |k,_| k == :default || k == :default_if }
12
+ def extract(association_name, object, local_options, options = {})
13
+ options_without_default = options.reject { |k, _| %i[default default_if].include?(k) }
14
14
  # Merge in assocation options hash
15
15
  local_options = local_options.merge(options[:options]) if options[:options].is_a?(Hash)
16
16
  value = @extractor.extract(association_name, object, local_options, options_without_default)
17
17
  return default_value(options) if use_default_value?(value, options[:default_if])
18
+
18
19
  view = options[:view] || :default
19
20
  blueprint = association_blueprint(options[:blueprint], value)
20
21
  blueprint.prepare(value, view_name: view, local_options: local_options)
@@ -3,7 +3,7 @@
3
3
  module Blueprinter
4
4
  # @api private
5
5
  class BlockExtractor < Extractor
6
- def extract(field_name, object, local_options, options = {})
6
+ def extract(_field_name, object, local_options, options = {})
7
7
  options[:block].call(object, local_options)
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Blueprinter
4
4
  # @api private
5
5
  class PublicSendExtractor < Extractor
6
- def extract(field_name, object, local_options, options = {})
6
+ def extract(field_name, object, _local_options, _options = {})
7
7
  object.public_send(field_name)
8
8
  end
9
9
  end
@@ -1,65 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api private
4
- class Blueprinter::Field
5
- attr_reader :method, :name, :extractor, :options, :blueprint
6
- def initialize(method, name, extractor, blueprint, options = {})
7
- @method = method
8
- @name = name
9
- @extractor = extractor
10
- @blueprint = blueprint
11
- @options = options
12
- end
4
+ module Blueprinter
5
+ class Field
6
+ attr_reader :method, :name, :extractor, :options, :blueprint
13
7
 
14
- def extract(object, local_options)
15
- extractor.extract(method, object, local_options, options)
16
- end
8
+ def initialize(method, name, extractor, blueprint, options = {})
9
+ @method = method
10
+ @name = name
11
+ @extractor = extractor
12
+ @blueprint = blueprint
13
+ @options = options
14
+ end
17
15
 
18
- def skip?(field_name, object, local_options)
19
- return true if if_callable && !if_callable.call(field_name, object, local_options)
20
- unless_callable && unless_callable.call(field_name, object, local_options)
21
- end
16
+ def extract(object, local_options)
17
+ extractor.extract(method, object, local_options, options)
18
+ end
22
19
 
23
- private
20
+ def skip?(field_name, object, local_options)
21
+ return true if if_callable && !if_callable.call(field_name, object, local_options)
24
22
 
25
- def if_callable
26
- return @if_callable if defined?(@if_callable)
27
- @if_callable = callable_from(:if)
28
- end
23
+ unless_callable && unless_callable.call(field_name, object, local_options)
24
+ end
29
25
 
30
- def unless_callable
31
- return @unless_callable if defined?(@unless_callable)
32
- @unless_callable = callable_from(:unless)
33
- end
26
+ private
34
27
 
35
- def callable_from(condition)
36
- callable = old_callable_from(condition)
28
+ def if_callable
29
+ return @if_callable if defined?(@if_callable)
37
30
 
38
- if callable && callable.arity == 2
39
- Blueprinter::Deprecation.report("`:#{condition}` conditions now expects 3 arguments instead of 2.")
40
- ->(_field_name, obj, options) { callable.call(obj, options) }
41
- else
42
- callable
31
+ @if_callable = callable_from(:if)
32
+ end
33
+
34
+ def unless_callable
35
+ return @unless_callable if defined?(@unless_callable)
36
+
37
+ @unless_callable = callable_from(:unless)
38
+ end
39
+
40
+ def callable_from(condition)
41
+ callable = old_callable_from(condition)
42
+
43
+ if callable && callable.arity == 2
44
+ Blueprinter::Deprecation.report("`:#{condition}` conditions now expects 3 arguments instead of 2.")
45
+ ->(_field_name, obj, options) { callable.call(obj, options) }
46
+ else
47
+ callable
48
+ end
43
49
  end
44
- end
45
50
 
46
- def old_callable_from(condition)
47
- config = Blueprinter.configuration
51
+ def old_callable_from(condition)
52
+ config = Blueprinter.configuration
48
53
 
49
- # Use field-level callable, or when not defined, try global callable
50
- tmp = if options.key?(condition)
51
- options.fetch(condition)
52
- elsif config.valid_callable?(condition)
53
- config.public_send(condition)
54
- end
54
+ # Use field-level callable, or when not defined, try global callable
55
+ tmp = if options.key?(condition)
56
+ options.fetch(condition)
57
+ elsif config.valid_callable?(condition)
58
+ config.public_send(condition)
59
+ end
55
60
 
56
- return false unless tmp
61
+ return false unless tmp
57
62
 
58
- case tmp
59
- when Proc then tmp
60
- when Symbol then blueprint.method(tmp)
61
- else
62
- raise ArgumentError, "#{tmp.class} is passed to :#{condition}"
63
+ case tmp
64
+ when Proc then tmp
65
+ when Symbol then blueprint.method(tmp)
66
+ else
67
+ raise ArgumentError, "#{tmp.class} is passed to :#{condition}"
68
+ end
63
69
  end
64
70
  end
65
71
  end
@@ -26,7 +26,7 @@ module Blueprinter
26
26
  when Proc then format.call(value)
27
27
  when String then value.strftime(format)
28
28
  else
29
- raise InvalidDateTimeFormatterError, 'Cannot format DateTime object with invalid formatter: #{format.class}'
29
+ raise InvalidDateTimeFormatterError, "Cannot format DateTime object with invalid formatter: #{format.class}"
30
30
  end
31
31
  end
32
32
  end
@@ -35,7 +35,8 @@ module Blueprinter
35
35
 
36
36
  def prepend_root_and_meta(data, root, meta)
37
37
  return data unless root
38
- ret = {root => data}
38
+
39
+ ret = { root => data }
39
40
  meta ? ret.merge!(meta: meta) : ret
40
41
  end
41
42
 
@@ -46,6 +47,7 @@ module Blueprinter
46
47
  def object_to_hash(object, view_name:, local_options:)
47
48
  result_hash = view_collection.fields_for(view_name).each_with_object({}) do |field, hash|
48
49
  next if field.skip?(field.name, object, local_options)
50
+
49
51
  hash[field.name] = field.extract(object, local_options)
50
52
  end
51
53
  view_collection.transformers(view_name).each do |transformer|
@@ -59,9 +61,9 @@ module Blueprinter
59
61
  when String, Symbol
60
62
  # no-op
61
63
  when NilClass
62
- raise BlueprinterError, "meta requires a root to be passed" if meta
64
+ raise BlueprinterError, 'meta requires a root to be passed' if meta
63
65
  else
64
- raise BlueprinterError, "root should be one of String, Symbol, NilClass"
66
+ raise BlueprinterError, 'root should be one of String, Symbol, NilClass'
65
67
  end
66
68
  end
67
69
 
@@ -71,10 +73,10 @@ module Blueprinter
71
73
 
72
74
  def validate_blueprint!(blueprint, method)
73
75
  validate_presence_of_blueprint!(blueprint)
74
- unless dynamic_blueprint?(blueprint)
75
- validate_blueprint_has_ancestors!(blueprint, method)
76
- validate_blueprint_has_blueprinter_base_ancestor!(blueprint, method)
77
- end
76
+ return if dynamic_blueprint?(blueprint)
77
+
78
+ validate_blueprint_has_ancestors!(blueprint, method)
79
+ validate_blueprint_has_blueprinter_base_ancestor!(blueprint, method)
78
80
  end
79
81
 
80
82
  def validate_presence_of_blueprint!(blueprint)
@@ -86,10 +88,10 @@ module Blueprinter
86
88
  # it means it, at the very least, does not have Blueprinter::Base as
87
89
  # one of its ancestor classes (e.g: Hash) and thus an error should
88
90
  # be raised.
89
- unless blueprint.respond_to?(:ancestors)
90
- raise BlueprinterError, "Blueprint provided for #{association_name} "\
91
+ return if blueprint.respond_to?(:ancestors)
92
+
93
+ raise BlueprinterError, "Blueprint provided for #{association_name} " \
91
94
  'association is not valid.'
92
- end
93
95
  end
94
96
 
95
97
  def validate_blueprint_has_blueprinter_base_ancestor!(blueprint, association_name)
@@ -98,9 +100,9 @@ module Blueprinter
98
100
  return if blueprint.ancestors.include? Blueprinter::Base
99
101
 
100
102
  # Raise error describing what's wrong.
101
- raise BlueprinterError, "Class #{blueprint.name} does not inherit from "\
102
- 'Blueprinter::Base and is not a valid Blueprinter '\
103
- "for #{association_name} association."
103
+ raise BlueprinterError, "Class #{blueprint.name} does not inherit from " \
104
+ 'Blueprinter::Base and is not a valid Blueprinter ' \
105
+ "for #{association_name} association."
104
106
  end
105
107
 
106
108
  def jsonify(blob)
@@ -4,11 +4,11 @@ module Blueprinter
4
4
  # @api private
5
5
  class Transformer
6
6
  def transform(_result_hash, _primary_obj, _options = {})
7
- fail NotImplementedError, "A Transformer must implement #transform"
7
+ raise NotImplementedError, 'A Transformer must implement #transform'
8
8
  end
9
9
 
10
10
  def self.transform(result_hash, primary_obj, options = {})
11
- self.new.transform(result_hash, primary_obj, options)
11
+ new.transform(result_hash, primary_obj, options)
12
12
  end
13
13
  end
14
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Blueprinter
4
- VERSION = '1.1.1'
4
+ VERSION = '1.1.2'
5
5
  end
@@ -20,14 +20,14 @@ module Blueprinter
20
20
  view_transformers.empty? ? Blueprinter.configuration.default_transformers : view_transformers
21
21
  end
22
22
 
23
- def track_definition_order(method, is_view = true)
24
- if @sort_by_definition
25
- @definition_order << DefinitionPlaceholder.new(method, is_view)
26
- end
23
+ def track_definition_order(method, viewable: true)
24
+ return unless @sort_by_definition
25
+
26
+ @definition_order << DefinitionPlaceholder.new(method, viewable)
27
27
  end
28
28
 
29
29
  def inherit(view)
30
- view.fields.values.each do |field|
30
+ view.fields.each_value do |field|
31
31
  self << field
32
32
  end
33
33
 
@@ -71,7 +71,7 @@ module Blueprinter
71
71
  end
72
72
 
73
73
  def <<(field)
74
- track_definition_order(field.name,false)
74
+ track_definition_order(field.name, viewable: false)
75
75
  fields[field.name] = field
76
76
  end
77
77
  end
@@ -4,6 +4,7 @@ module Blueprinter
4
4
  # @api private
5
5
  class ViewCollection
6
6
  attr_reader :views, :sort_by_definition
7
+
7
8
  def initialize
8
9
  @views = {
9
10
  identifier: View.new(:identifier),
@@ -18,8 +19,8 @@ module Blueprinter
18
19
  end
19
20
  end
20
21
 
21
- def has_view?(view_name)
22
- views.has_key? view_name
22
+ def view?(view_name)
23
+ views.key? view_name
23
24
  end
24
25
 
25
26
  def fields_for(view_name)
@@ -28,8 +29,8 @@ module Blueprinter
28
29
  fields, excluded_fields = sortable_fields(view_name)
29
30
  sorted_fields = sort_by_definition ? sort_by_def(view_name, fields) : fields.values.sort_by(&:name)
30
31
 
31
- (identifier_fields + sorted_fields).tap do |fields|
32
- fields.reject! { |field| excluded_fields.include?(field.name) }
32
+ (identifier_fields + sorted_fields).tap do |fields_array|
33
+ fields_array.reject! { |field| excluded_fields.include?(field.name) }
33
34
  end
34
35
  end
35
36
 
@@ -69,7 +70,9 @@ module Blueprinter
69
70
  # select and order members of fields according to traversal of the definition_orders
70
71
  def sort_by_def(view_name, fields)
71
72
  ordered_fields = {}
72
- views[:default].definition_order.each { |definition| add_to_ordered_fields(ordered_fields, definition, fields, view_name) }
73
+ views[:default].definition_order.each do |definition|
74
+ add_to_ordered_fields(ordered_fields, definition, fields, view_name)
75
+ end
73
76
  ordered_fields.values
74
77
  end
75
78
 
@@ -78,7 +81,9 @@ module Blueprinter
78
81
  def add_to_ordered_fields(ordered_fields, definition, fields, view_name_filter = nil)
79
82
  if definition.view?
80
83
  if view_name_filter.nil? || view_name_filter == definition.name
81
- views[definition.name].definition_order.each { |_definition| add_to_ordered_fields(ordered_fields, _definition, fields) }
84
+ views[definition.name].definition_order.each do |defined|
85
+ add_to_ordered_fields(ordered_fields, defined, fields)
86
+ end
82
87
  end
83
88
  else
84
89
  ordered_fields[definition.name] = fields[definition.name]