Class: Porridge::SerializerWithRoot

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

Overview

SerializerWithRoot is a serializer that wraps another serializer and adds a “root key” to the resulting hash.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Serializer

ensure_valid!, valid?

Constructor Details

#initialize(base, root_key: nil) ⇒ SerializerWithRoot

Creates a new instance of Porridge::SerializerWithRoot with the given base serializer and, optionally, root key.

Parameters:

  • base (Serializer, #call)

    the base serializer to wrap.

  • root_key (defaults to: nil)

    the “root” key to inject into the resulting hash. If nil, which is the default, the root key will be inferred from the object.

Raises:



14
15
16
17
18
19
# File 'lib/porridge/serializer_with_root.rb', line 14

def initialize(base, root_key: nil)
  Serializer.ensure_valid!(base)
  @base = base
  @root_key = root_key
  super()
end

Instance Attribute Details

#baseSerializer, #call (readonly, private)

The base serializer to wrap.

Returns:



81
82
83
# File 'lib/porridge/serializer_with_root.rb', line 81

def base
  @base
end

#root_keyObject (readonly, private)

The explicit root key; if nil, will be inferred.



84
85
86
# File 'lib/porridge/serializer_with_root.rb', line 84

def root_key
  @root_key
end

Instance Method Details

#array?(object) ⇒ Boolean (protected)

Determines whether the given object functions like an array for the purposes of this Porridge::SerializerWithRoot. The default implementation checks to see whether the object implements both #map and #first. You may override the default behavior by overriding this method. Note that if you override ArraySerializer#like_array? you will likely wish to override this method as well.

Parameters:

  • object

    the object to check.

Returns:

  • (Boolean)

    true if the given object is like an array; false otherwise.



50
51
52
# File 'lib/porridge/serializer_with_root.rb', line 50

def array?(object)
  object.respond_to?(:map) && object.respond_to?(:first)
end

#base_root_key(object) ⇒ String (private)

Gets the inferred base root key, without singularization or pluralization for the given object.

Parameters:

  • object

    the object for which to get the base root key.

Returns:

  • (String)

    the resolved base root key.



69
70
71
# File 'lib/porridge/serializer_with_root.rb', line 69

def base_root_key(object)
  representative_sample(object).class.name.underscore.to_s
end

#call(object, input, options) ⇒ Hash

Serializes the given input for the given object with the given options by delegating to the base serializer (#base) and adding a root key to the resulting hash. Note that the output of the base serializer must be a hash.

If the root key was not set manually, it will be inferred from the “underscored” class name of the object. If the object is an array (according to #array?), then the class name will be derived from the first object in the array, and will be pluralized. Be aware that retrieving the first element of the “array” may cause an SQL query to be performed if the “array” is a Rails relation.

Note that an inferred root key is always a string. You may wish to use a KeyNormalizingSerializer if symbol keys are desired.

Parameters:

  • object

    the object for which to transform the input. If no root key was set manually, it will be inferred from the object’s class.

  • input

    the object being transformed, typically either a hash or an array.

  • options (Hash)

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

Returns:

  • (Hash)

    the hash returned from the base serializer, injected with a root key.



38
39
40
# File 'lib/porridge/serializer_with_root.rb', line 38

def call(object, input, options)
  { evaluate_root_key(object) => base.call(object, input, options) }
end

#evaluate_root_key(object) ⇒ Object (private)

Gets a root key for the given object by either returning #root_key, or returning a singular/plural version of the #base_root_key, depending on whether the object is an array.

Parameters:

  • object

    the object for which to get a root key.

Returns:

  • the resolved string root key.



60
61
62
63
64
# File 'lib/porridge/serializer_with_root.rb', line 60

def evaluate_root_key(object)
  return root_key if root_key

  array?(object) ? base_root_key(object).pluralize : base_root_key(object).singularize
end

#representative_sample(object) ⇒ Object (private)

Gets a “representative” sample from the given object. In practice, this means either returning the object itself, or, if the object is an array-like structure, returning the first element.



75
76
77
# File 'lib/porridge/serializer_with_root.rb', line 75

def representative_sample(object)
  array?(object) ? object.first : object
end