Module: ActiveModelSerializerPlus

Defined in:
lib/active_model_serializer_plus/translations.rb,
lib/active_model_serializer_plus/railtie.rb,
lib/active_model_serializer_plus/version.rb,
lib/active_model_serializer_plus/assignment.rb

Overview

Top-level namespace for the ActiveModelSerializerPlus extensions.

The methods and module variables here aren’t commonly used directly by applications, they’re mainly for internal use by the Assignment, JSON and Xml namespaces. You’ll want to become familiar with the contents if you want to extend the set of types/classes handled automatically during serialization and deserialization.

Currently the formatting-related functionality is unused. It’s included for use in a planned XML serialization/deserialization extension.

Author:

Defined Under Namespace

Modules: Assignment Classes: Railtie

Constant Summary collapse

VERSION =

Version number.

"1.1.0"

Class Method Summary collapse

Class Method Details

.add_arraylike_container(typename) ⇒ void

This method returns an undefined value.

Add a new kind of Array-like container

Parameters:

  • typename (String)

    type name of the container type to add



109
110
111
112
113
114
115
# File 'lib/active_model_serializer_plus/assignment.rb', line 109

def self.add_arraylike_container(typename)
    return if typename.blank?
    @@container_iterators[typename] = @@build_from_arraylike_proc
    @@container_adders[typename] = @@add_to_arraylike_proc
    ActiveModelSerializerPlus.add_xlate(typename, 'Container')
    return
end

.add_container(typename, iterator_proc, adder_proc) ⇒ void

This method returns an undefined value.

Add iterator and adder procs for a new kind of container.

Parameters:

  • typename (String)

    type name of the container type to add

  • iterator_proc (Proc)

    Proc to build from that type of container

  • adder_proc (Proc)

    Proc to add an item to that type of container



98
99
100
101
102
103
104
# File 'lib/active_model_serializer_plus/assignment.rb', line 98

def self.add_container(typename, iterator_proc, adder_proc)
    return if typename.blank? || iterator_proc.nil? || adder_proc.nil?
    @@container_iterators[typename] = iterator_proc
    @@container_adders[typename] = adder_proc
    ActiveModelSerializerPlus.add_xlate(typename, 'Container')
    return
end

.add_hashlike_container(typename) ⇒ void

This method returns an undefined value.

Add a new kind of Hash-like container

Parameters:

  • typename (String)

    type name of the container type to add



120
121
122
123
124
125
126
# File 'lib/active_model_serializer_plus/assignment.rb', line 120

def self.add_hashlike_container(typename)
    return if typename.blank?
    @@container_iterators[typename] = @@build_from_hashlike_proc
    @@container_adders[typename] = @@add_to_hashlike_proc
    ActiveModelSerializerPlus.add_xlate(typename, 'Container')
    return
end

.add_type(type_name, formatting_proc = nil, parsing_proc = nil, building_proc = nil) ⇒ void

This method returns an undefined value.

Add information about a new type to the formatting/parsing/building hashes. type_name is required, all others are optional and should be specified as nil if not being defined.

Parameters:

  • type_name (String)

    name of the type to add

  • formatting_proc (Proc) (defaults to: nil)

    Proc to add to format an object’s value into a string

  • parsing_proc (Proc) (defaults to: nil)

    Proc to add to parse a string value and create an object from it

  • building_proc (Proc) (defaults to: nil)

    Proc to add to create an object from a hash of attribute names and values



162
163
164
165
166
167
168
# File 'lib/active_model_serializer_plus/translations.rb', line 162

def self.add_type(type_name, formatting_proc = nil, parsing_proc = nil, building_proc = nil)
    return if type_name.blank?
    @@formatting[type_name] = formatting_proc unless formatting_proc.nil?
    @@parsing[type_name] = parsing_proc unless parsing_proc.nil?
    @@building[type_name] = building_proc unless building_proc.nil?
    return
end

.add_xlate(type_name, parent_type_name) ⇒ void

This method returns an undefined value.

Add a new type translation. Translations are used to create pseudo-parent classes in cases where several classes can use common Procs for formatting, parsing and/or building but don’t share a common parent class, eg. TrueClass and FalseClass which can both use the Boolean formatting and parsing Procs.

Parameters:

  • type_name (String)

    name of the specific type

  • parent_type_name (String)

    name of the pseudo-parent type



148
149
150
151
152
# File 'lib/active_model_serializer_plus/translations.rb', line 148

def self.add_xlate( type_name, parent_type_name )
    return if type_name.blank?
    @@type_name_xlate[type_name] = parent_type_name unless parent_type_name.blank?
    return
end

.build(class_name, hash) ⇒ Object

Build an object of the named type from a hash if a building Proc is defined.

Parameters:

  • class_name (String)

    name of the class of object being built from the hash

  • hash (Hash)

    hash containing the attribute names and values from which the object is to be built

Returns:

  • (Object)

    the new object, or nil if no building Proc for class_name is defined



134
135
136
137
138
139
# File 'lib/active_model_serializer_plus/translations.rb', line 134

def self.build(class_name, hash)
    p = nil
    xlt = @@type_name_xlate[class_name] || class_name
    p = @@building[xlt] unless xlt.nil?
    p ? p.call(hash) : nil
end

.build_object(obj_klass, value) ⇒ Object

Break out the logic for creating a new object of a class from a hash or string value. It’s needed for both individual attributes and for each element of a container.

Parameters:

  • obj_klass (Class)

    class of the object to create

  • value (String, Hash)

    value to use to initialize the object

Returns:

  • (Object)

    newly-created object or nil

Raises:

  • (ArgumentError)

    if the object cannot be created



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/active_model_serializer_plus/assignment.rb', line 73

def self.build_object(obj_klass, value)
    obj = nil
    if value.is_a?(Hash)
        # If we're looking at a contained object (our value is a hash), see if we have a Proc
        # to build the object from a hash. If we don't, fall back to creating an object and
        # using the hash #attributes= method if possible. If all else fails just leave the value
        obj = ActiveModelSerializerPlus.build(obj_klass.name, value)
        if obj.nil? && obj_klass.method_defined?('attributes=')
            obj = obj_klass.new
            if obj.nil?
                raise ArgumentError, "Cannot create object of type #{obj_klass.name}."
            end
            obj.attributes = value
        end
    elsif value.is_a?(String)
        obj = ActiveModelSerializerPlus.parse(obj_klass.name, value)
    end
    obj
end

.format(value) ⇒ String

Note:

If no formatting Proc is defined, #to_s is used instead.

Note:

Checks all parent classes of value for Procs.

Format a value into a string using the defined formatting Proc for value‘s class.

Parameters:

  • value (Object)

    the value to format

Returns:

  • (String)

    the value formatted into a string



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active_model_serializer_plus/translations.rb', line 82

def self.format(value)
    # Check the translation table first for a pseudo-parent, and if we found one check
    # for it's proc. Then start with the value's class name and work up through it's
    # parent classes until we find a proc for one. If we can't find a proc, just use
    # the #to_s method.
    p = nil
    n = @@type_name_xlate[value.class.name]
    p = @@formatting[n] unless n.nil?
    if p.nil?
        b = value.class
        until b.nil? do
            p = @@formatting[b.name]
            break unless p.nil?
            b = b.superclass
        end
    end
    p ? p.call(value) : value.to_s
end

.get_container_adder(typename) ⇒ Object

Look up adder proc.



62
63
64
# File 'lib/active_model_serializer_plus/assignment.rb', line 62

def self.get_container_adder(typename)
    @@container_adders[typename]
end

.get_container_iterator(typename) ⇒ Object

Look up iterator proc.



57
58
59
# File 'lib/active_model_serializer_plus/assignment.rb', line 57

def self.get_container_iterator(typename)
    @@container_iterators[typename]
end

.parse(class_name, value) ⇒ Object

Note:

Checks all parent classes of class_name for Procs.

Parse a string value into an object of the named type if a parsing Proc is defined.

Parameters:

  • class_name (String)

    name of the class of object being created from the value

  • value (String)

    the string containing the formatted value to be parsed

Returns:

  • (Object)

    the new object, or nil if no parsing Proc for class_name is defined



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/active_model_serializer_plus/translations.rb', line 106

def self.parse(class_name, value)
    # Check for a proc for the type name given, and if we find one use it. Otherwise
    # try to convert that name to a class. If we can, start with it and work up through
    # it's parent classes checking for a proc for each. If we can't find a proc, return
    # nil.
    p = nil
    xlt = @@type_name_xlate[class_name] || class_name
    p = @@parsing[xlt] unless xlt.nil?
    if p.nil?
        klass = nil
        begin
            klass = class_name.constantize
        rescue NameError
            klass = nil
        end
        until klass.nil?
            p = @@parsing[klass.name]
            break unless p.nil?
            klass = klass.superclass
        end
    end
    p ? p.call(value.to_s) : nil
end

.to_class(class_name) ⇒ Class

Helper method to convert a type/class name into an actual class.

Parameters:

  • class_name (Class, Symbol, String)

    name to convert into a Class object

Returns:

  • (Class)

    Class object for the named class

Raises:

  • (ArgumentError)

    if class_name is not of an acceptable type

  • (NameError)

    if class_name is a Class that doesn’t exist



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/active_model_serializer_plus/translations.rb', line 175

def self.to_class(class_name)
    klass = nil
    if class_name.is_a?(Class)
        klass = class_name
    elsif class_name.is_a?(String)
        begin
            klass = class_name.constantize unless class_name.blank?
        rescue NameError
            raise ArgumentError, "Type #{class_name} is invalid"
        end
    elsif class_name.is_a?(Symbol)
        begin
            klass = class_name.to_s.constantize
        rescue NameError
            raise ArgumentError, "Type #{class_name.to_s} is invalid"
        end
    else
        raise ArgumentError, "Type #{class_name.to_s} is invalid"
    end
    klass
end

.to_classname(class_name) ⇒ String

Helper method to convert a representation of a class or class name into a string containing the class name.

Parameters:

  • class_name (Class, Symbol, String)

    the Class whose name you need or a symbol or string representing a class name

Returns:

  • (String)

    the class name represented by class_name converted to a string

Raises:

  • (ArgumentError)

    if class_name is not of an acceptable type

  • (NameError)

    if class_name is a Class that doesn’t exist



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/active_model_serializer_plus/translations.rb', line 202

def self.to_classname(class_name)
    klassname = nil
    if class_name.is_a?(Class)
        klassname = class_name.name
    elsif class_name.is_a?(String)
        klassname = class_name
    elsif class_name.is_a?(Symbol)
        klassname = class_name.to_s
    else
        raise ArgumentError, "Argument type #{class_name.class.name} is not Class, String or Symbol"
    end
    klassname
end

.type_name_xlate(class_name) ⇒ String

Translate a type/class name to it’s psuedo-parent class name if it has one.

Parameters:

  • class_name (String)

    the name of the class to translate

Returns:

  • (String)

    the translated name



73
74
75
# File 'lib/active_model_serializer_plus/translations.rb', line 73

def self.type_name_xlate(class_name)
    @@type_name_xlate[class_name]
end