Class: Porridge::FieldSerializer

Inherits:
Serializer show all
Defined in:
lib/porridge/field_serializer.rb

Overview

FieldSerializer is a serializer that adds a “field” to a hash. It does so by using a predefined “field name” as the key and evaluates an Extractor for the object for the value.

FieldSerializer is the most opinionated piece of the porridge framework. In particular, it adds to a :field_hierarchy array in the options hash to keep track of nested fields. It also requires the use of a FieldPolicy object given in the options to determine whether a given field is allowed. Do not be afraid to subclass FieldSerializer or even create a new “field serializer” class altogether if you want to substantially change the way fields are implemented.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Serializer

ensure_valid!, valid?

Constructor Details

#initialize(name, extractor) ⇒ FieldSerializer

Creates a new instance of Porridge::FieldSerializer with the given field name and value extractor.

Parameters:

  • name

    the name of the field; will be used as the key for the field in the hash.

  • extractor (Extractor, #call)

    the value extractor to use to retrieve a value from the object, which will be used as the value for the field in the hash.

Raises:



18
19
20
21
22
23
# File 'lib/porridge/field_serializer.rb', line 18

def initialize(name, extractor)
  @name = name
  @extractor = extractor
  Extractor.ensure_valid!(extractor)
  super()
end

Instance Attribute Details

#extractorExtractor, #call (readonly, private)

The value extractor to use to retrieve a value from the object for which serialization is occurring.

Returns:



86
87
88
# File 'lib/porridge/field_serializer.rb', line 86

def extractor
  @extractor
end

#nameObject (readonly, private)

The name of the field being serialized by this Porridge::FieldSerializer; used as the key for the field in the hash.



82
83
84
# File 'lib/porridge/field_serializer.rb', line 82

def name
  @name
end

Instance Method Details

#add_field_to_hierarchy!(options_hash) ⇒ void (private)

This method returns an undefined value.

Safely adds the current #name to the :field_hierarchy in the given options hash. While the options hash itself is mutated, the field hierarchy array is first duplicated, meaning the options hash must have first been duplicated for this to be safe.

Parameters:

  • options_hash (Hash)

    the options hash to which the field should be added.



66
67
68
69
70
# File 'lib/porridge/field_serializer.rb', line 66

def add_field_to_hierarchy!(options_hash)
  options_hash[:field_hierarchy] ||= []
  options_hash[:field_hierarchy] = options_hash[:field_hierarchy].dup
  options_hash[:field_hierarchy] << name
end

#allowed?(object, options) ⇒ Boolean (private)

Determines whether the given object/options, along with the current #name constitutes a valid field. Currently, this is done by simply delegating to the field policy which should have been provided as an option.

Parameters:

  • object

    the object for which the field being validated is being implemented.

  • options (Hash)

    the options for which the field being validated is being implemented.

Returns:

  • (Boolean)

    true if the indicated field is valid; false otherwise.

Raises:

  • (InvalidFieldPolicyError)

    if no field policy was provided or if the field policy was not a valid field policy object.



56
57
58
59
# File 'lib/porridge/field_serializer.rb', line 56

def allowed?(object, options)
  FieldPolicy.ensure_valid!(options[:field_policy])
  options[:field_policy].allowed?(name, object, options.except(:field_policy))
end

#call(object, hash, options) ⇒ Hash

Serializes the given input hash for the given object with the given options by adding an element to the hash with a key that is equal to the field name (#name) and a value extracted from the object using the field extractor (#extractor).

Parameters:

  • object

    the object for which to transform the input. The field value will be retrieved from this object using the extractor.

  • hash (Hash)

    the input hash being transformed. A key-value pair will be added for the field.

  • options (Hash)

    a hash of “options,” which may be application specific.

Options Hash (options):

  • :field_policy (FieldPolicy, #allowed?)

    the field policy to use to determine whether the field is currently allowed. This option must be provided.

Returns:

  • (Hash)

    the transformed hash.

Raises:

  • (InvalidFieldPolicyError)

    if no field policy was provided or if the field policy was not a valid field policy object.



37
38
39
40
41
42
43
44
45
# File 'lib/porridge/field_serializer.rb', line 37

def call(object, hash, options)
  if allowed?(object, options)
    options = options.dup
    add_field_to_hierarchy!(options)
    hash_with_field(object, hash, options)
  else
    hash
  end
end

#hash_with_field(object, hash, options) ⇒ Hash (private)

Creates a new hash from the given one with a field for the given object injected.

Parameters:

  • object

    the object for which to inject the field. Will be passed to the extractor.

  • hash (Hash)

    the hash into which to inject the field.

  • options (Hash)

    the options for which to inject the field. Will be passed to the extractor.

Returns:

  • (Hash)

    the transformed hash.



77
78
79
# File 'lib/porridge/field_serializer.rb', line 77

def hash_with_field(object, hash, options)
  hash.merge(name => extractor.call(object, options))
end