Wednesday, November 14, 2007

to_xml, almost deep enough


Workout
has_many :laps

Lap
has_many :points
belongs_to :workout

Point
belongs_to :lap


I'd like to serialize it all. The first approach


render :xml => workout.to_xml(:include => :laps)

Cool, we get workout data with laps, but no points.



Reading through the to_xml implementation it makes sense that you can only get to first level associations. For my purposes, I just wanted to avoid repeating my data model in my rxml files.



Here's what I came up with.


module Builder
class XmlMarkup
def add_record!(record,options = {})
options = {:builder => self,:skip_instruct => true}.merge!(options)
ActiveRecord::XmlSerializer.new(record, options).serialize
end

def add_record_attributes!(record)
record.attribute_names.each do|name|
attr = ActiveRecord::XmlSerializer::Attribute.new(name,record)
tag!( attr.name, attr.value.to_s, attr.decorations )
end
end
end
end



Now, in my rxml view I can write this.
xml.instruct!( :xml, :version=>"1.0", :encoding=>"UTF-8" )
xml.workout do
xml.add_record_attributes!(@workout)
xml.laps do
@workout.laps.each do|lap|
xml.add_record!(lap, :include => :points)
end
end
end

0 comments:

Reading list