Module: Consumer::Mapping::ClassMethods

Defined in:
lib/consumer/mapping.rb

Instance Method Summary collapse

Instance Method Details

#from_hash(attrs) ⇒ Object

initializes a new instance of self and uses the attribute setters to populate attributes from the hash. Objects inheriting from ActiveRecord do this automatically in initialize, but the world doesn’t (always) revolve around AR



138
139
140
141
142
143
144
145
146
# File 'lib/consumer/mapping.rb', line 138

def from_hash(attrs)
  object = self.new

  attrs.each do |attribute, value|
    object.send("#{attribute}=", value)
  end

  object
end

#from_xml(xml) ⇒ Object

you can override this to what you want. Defaults to an alias for from_xml_via_map.



128
129
130
131
132
# File 'lib/consumer/mapping.rb', line 128

def from_xml(xml)
  @xml = xml
  self.before_from_xml if defined?(before_from_xml)
  from_xml_via_map(@xml)
end

#from_xml_via_map(xml) ⇒ Object

Pulls attributes from the xml using xpaths defined in the mapping whose base path matches the xml, and instantiates a new object with those attrs.

Behaviors

  • If multiple elements match the base path and map is true, it will return an array of objects.

  • Calls from_xml on elements in map (see association_from_xml)

  • Calls map with the new instance (and optionally the libxml node) just before adding it to the return array for custom post-processing

Returns

  • An array of instances or a new instance depending on whether map is true or false, respectively



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/consumer/mapping.rb', line 95

def from_xml_via_map(xml)
  nodes, map = find_nodes_and_map(xml)
  return nil if map.nil?
  instances = []

  nodes.each do |node|
    attrs = attrs_from_node_and_registry(node, map[:registry])
    instance = self.from_hash(attrs)
    
    map[:associations].each do |association|
      # TODO: spec
      instance.association_from_xml(node.to_s, association)
    end
    
    b = map[:block]
    if b
      case b.arity # number of parameters
      when 1
        b.call(instance)
      when 2
        b.call(instance, node)
      end
    end
    
    return instance unless map[:all]
    instances << instance
  end
  
  return instances
end

#map(first_or_all, base_path, registry, options = {}, &block) ⇒ Object

Creates a new mapping hash in self.maps

Parameters

The parameters here are used to add a new mapping hash to self.maps, which in turn is used by from_xml_via_map to instantiate new objects

first_or_all

If :all, from_xml_via_map will return an array instead of a single instance (i.e. sets map to true)

base_path

A fully qualified xpath, such as //SomethingResponse/bah. Also, uniquely identifies the map for a particular xml response in the case of multiple maps.

registry

A hash of :attribute => ‘xpath’ pairs. Xpaths are relative to base_path, but fully qualified xpaths are also valid.

For example, if the base path was //Response/Bah and the registry was => “FooElm”, then from_xml_via_map will set instance.foo to the value at //Response/Bah/FooElm in the xml. However, if you set => “//Response/Woot/Ack”, then it will pull the value from //Response/Woot/Ack (not //Response/Bah/Response/Woot/Ack).

options

Valid options are:

  • :include - sets map, which is an array of parameters to association_from_xml

block

In from_xml_via_map this gets called with the new instance as the last step of instantiation.

Returns

The newly created map

Raises

  • RuntimeError if the base path is already defined in another mapping in the class



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/consumer/mapping.rb', line 61

def map(first_or_all, base_path, registry, options = {}, &block)
  if self.maps.find {|m| m[:base_path] == base_path}
    raise "Base path exists: #{base_path}" 
  end
  
  map = {
    :all => first_or_all == :all ? true : false,
    :base_path => base_path,
    :registry => registry,
    :associations => [*options[:include]].compact,
    :block => block
  }
  self.maps << map
  
  return map
end

#mapsObject

Returns @maps or []



79
80
81
# File 'lib/consumer/mapping.rb', line 79

def maps
  @maps ||= []
end