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