blueprinter-rb 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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]