Class: Beerxml::Model

Inherits:
Object
  • Object
show all
Includes:
Properties, DataMapper::Resource
Defined in:
lib/beerxml/model.rb

Direct Known Subclasses

Fermentable, Hop, Recipe, Yeast

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.beerxml_nameObject



11
12
13
# File 'lib/beerxml/model.rb', line 11

def self.beerxml_name
  name.split('::').last.upcase
end

.beerxml_plural_nameObject



15
16
17
# File 'lib/beerxml/model.rb', line 15

def self.beerxml_plural_name
  "#{beerxml_name}S"
end

.collection_from_xml(collection_node) ⇒ Object

takes a collection root xml node, like <HOPS>, and returns an array of the child model objects inside the node.



59
60
61
62
63
64
65
# File 'lib/beerxml/model.rb', line 59

def self.collection_from_xml(collection_node)
  model = @plurals[collection_node.name]
  raise("Unknown model: #{collection_node.name}") unless model
  (collection_node>model.beerxml_name).map do |child_node|
    model.new.from_xml(child_node)
  end
end

.from_xml(node) ⇒ Object

Takes a Nokogiri node, figures out what sort of class it is, and parses it. Raises if it’s not a Beerxml::Model class (or collection).



29
30
31
32
33
34
35
36
37
# File 'lib/beerxml/model.rb', line 29

def self.from_xml(node)
  if model = @models[node.name]
    model.new.from_xml(node)
  elsif model = @plurals[node.name]
    collection_from_xml(node)
  else
    raise "Unknown BeerXML node type: #{node.name}"
  end
end

.inherited(klass) ⇒ Object



19
20
21
22
23
# File 'lib/beerxml/model.rb', line 19

def self.inherited(klass)
  super
  @models[klass.beerxml_name] = klass
  @plurals["#{klass.beerxml_name}S"] = klass
end

.xml_attr_name(name) ⇒ Object



101
102
103
# File 'lib/beerxml/model.rb', line 101

def self.xml_attr_name(name)
  name.to_s.upcase
end

Instance Method Details

#beerxml_relationshipsObject



105
106
107
# File 'lib/beerxml/model.rb', line 105

def beerxml_relationships
  []
end

#each_beerxml_relationshipObject



109
110
111
112
113
114
# File 'lib/beerxml/model.rb', line 109

def each_beerxml_relationship
  relationships.each do |name, rel|
    next unless beerxml_relationships.include?(rel.name)
    yield rel
  end
end

#from_xml(node) ⇒ Object

Parse a Nokogiri node, reading in the properties defined on this model. Assumes the node is of the correct type.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/beerxml/model.rb', line 41

def from_xml(node)
  properties.each do |property|
    read_xml_field(node, property.name.to_s)
  end
  # load any has-many relationships with other beerxml models
  each_beerxml_relationship do |rel|
    # look for the plural element in the children of this node
    # e.g., for Hop, see if there's any HOPS element.
    (node>rel.child_model.beerxml_plural_name).each do |child_wrapper_node|
      collection = Beerxml::Model.collection_from_xml(child_wrapper_node)
      self.send(rel.name).concat(collection)
    end
  end
  self
end

#read_xml_field(node, attr_name, node_name = attr_name.upcase) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/beerxml/model.rb', line 67

def read_xml_field(node, attr_name, node_name = attr_name.upcase)
  child = (node>node_name).first
  return unless child
  child = child.text
  child = yield(child) if block_given?
  self.send("#{attr_name}=", child)
end

#to_beerxml(parent = Nokogiri::XML::Document.new) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/beerxml/model.rb', line 77

def to_beerxml(parent = Nokogiri::XML::Document.new)
  # TODO: do we raise an error if not valid?
  node = Nokogiri::XML::Node.new(self.class.beerxml_name, parent)
  attributes.each do |attr, val|
    next if attr.to_s.match(/id\z/) || val.nil?
    x = Nokogiri::XML::Node.new(self.class.xml_attr_name(attr), parent)
    x.content = self.class.properties[attr].dump(val)
    node.add_child(x)
  end
  each_beerxml_relationship do |rel|
    objs = self.send(rel.name)
    next if objs.empty?
    sub_node = Nokogiri::XML::Node.new(rel.child_model.beerxml_plural_name, node)
    node.add_child(sub_node)
    objs.each { |o| o.to_beerxml(sub_node) }
  end
  parent.add_child(node)
  parent
end

#to_xmlObject



97
98
99
# File 'lib/beerxml/model.rb', line 97

def to_xml
  to_beerxml.to_s
end