I'm working on an XML export for a Ruby project and I'm looking for an elegant way to implement it. The goal of this XML file is to export all data inside a project container and there is several models (about 20) sharing some common properties (for example a name and a description).
Currently, the XML export looks like an awful thing like that:
def export_project(p)
@xml project {
@xml.name p.name
@xml.description p.description
@xml.itemAs {
p.item_as.each {|item_a|export_itemA(item_a)
}
@xml.itemBs {
p.item_Bs.each {|item_B|export_itemB(item_b)
}
@xml.itemCs {
p.item_cs.each {|item_c|export_itemC(item_c)
}
}
end
def export_itemA(a)
@xml.itemA {
@xml.name a.name
}
end
def export_itemB(b)
@xml.itemB {
@xml.description b.description
}
end
def export_itemC(c)
@xml.itemC {
@xml.name c.name
@xml.description c.description
}
end
Which is pretty ugly (well, it's bearrable with 4 types, but the reality is 480 lines of mess ...)
What I'd like would be something like that (considered there is a magic mapping between a model and an exporter):
module Named
def export
@xml.name @context.name
end
end
module Described
def export
@xml.description @context.description
end
end
class ProjectExporter < ModelExporter
include Named
include Described
def export
@xml.project {
super
@xml.itemAs {
export_items(p.item_as)
}
@xml.itemBs {
export_items(p.item_Bs)
}
@xml.itemCs {
export_items(p.item_cs)
}
}
end
class ItemAExporter < ModelExporter
include Named
def export
@xml.itemA {
super
}
end
end
class ItemBExporter < ModelExporter
include Described
def export
@xml.itemB {
super
}
end
end
class ItemCExporter < ModelExporter
include Named
include Described
def export
@xml.itemC {
super
}
end
end
The problem with this method is that "super" will only call the export method of one of the module, not all of them.
I'm pretty suer the module and super approach is not the correct one, but I'm unable to find something more suitable. Any idea ?
Cheers and thanks, Vincent