Note that there are some explanatory texts on larger screens.

plurals
  1. PORuby/Builder API: create XML without using blocks
    text
    copied!<p>I'd like to use <a href="http://builder.rubyforge.org/" rel="nofollow">Builder</a> to construct a set of XML files based on a table of ActiveRecord models. I have nearly a million rows, so I need to use <code>find_each(batch_size: 5000)</code> to iterate over the records and write an XML file for each batch of them, until the records are exhausted. Something like the following:</p> <pre><code>filecount = 1 count = 0 xml = "" Person.find_each(batch_size: 5000) do |person| xml += person.to_xml # pretend .to_xml() exists count += 1 if count == MAX_PER_FILE File.open("#{filecount}.xml", 'w') {|f| f.write(xml) } xml = "" filecount += 1 count = 0 end end </code></pre> <p>This doesn't work well with Builder's interface, as it wants to work in blocks, like so:</p> <pre><code>xml = builder.person { |p| p.name("Jim") } </code></pre> <p>Once the block ends, Builder closes its current stanza; you can't keep a reference to p and use it outside of the block (I tried). Basically, Builder wants to "own" the iteration.</p> <p>So to make this work with builder, I'd have to do something like:</p> <pre><code> filecount = 0 offset = 0 while offset &lt; Person.count do count = 0 builder = Builder::XmlMarkup.new(indent: 5) xml = builder.people do |people| Person.limit(MAX_PER_FILE).offset(offset).each do |person| people.person { |p| p.name(person.name) } count += 1 end end File.open("#output@file_count.xml", 'w') {|f| f.write(xml) } filecount += 1 offset += count end </code></pre> <p>Is there a way to use Builder without the block syntax? Is there a way to programmatically tell it "close the current stanza" rather than relying on a block?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload