views:

54

answers:

1

I have a controller that returns XML for a has_many association in the most straight-forward but inefficient way possible:

@atoms = @molecule.atoms.find(:all, :include => :neutrons)

render :xml => @atoms.to_xml(:root => 'atoms')

This fetches and instantiates all objects at once. To make this more memory efficient I'd like to use ActiveRecord's batched find. At first glance, this seems to be the only way to do it:

xml = '<atoms>'
@molecule.atoms.find_each(:include => :neutrons) do |atom|
  xml << atom.to_xml
end
xml << '</atoms>'

render :xml => xml

This is definitely more memory efficient but is decidedly less elegant. It duplicates some of the existing functionality of Array#to_xml.

Is there a way to harness the power of find_each without building XML by hand?

A: 

My usual approach to generating XML is to use the XML Builder template.

#in the controller
respond_to do |format|
  format.html # index.html.erb
  format.xml # index.xml.builder
end

#in index.xml.builder
xml.atoms {
  @molecule.atoms.find_each(:include => :neutrons) do |atom|
     #etc
  end
}
MattMcKnight
Ah, right. I'd forgotten about this. But I guess my concern is not where to do the building (for which this is definitely the best approach) but whether to do the building at all. I prefer the self-contained nature of being able to call `.to_xml` and it would be nice to find a way to swap out the `.each` that is used when generating a collection's XML with `.find_each`.
Ian