Builderを使用して、ActiveRecordモデルのテーブルに基づいて一連のXMLファイルを作成したいと思います。私は100万行近くあるのでfind_each(batch_size: 5000)
、レコードがなくなるまで、レコードを反復処理し、それらのバッチごとにXMLファイルを書き込むために使用する必要があります。次のようなもの:
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
これは、次のようにブロックで機能するため、Builderのインターフェイスではうまく機能しません。
xml = builder.person { |p| p.name("Jim") }
ブロックが終了すると、Builderは現在のスタンザを閉じます。pへの参照を保持して、ブロックの外で使用することはできません(私は試しました)。基本的に、Builderはイテレーションを「所有」したいと考えています。
したがって、ビルダーでこれを機能させるには、次のようなことを行う必要があります。
filecount = 0
offset = 0
while offset < 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
ブロック構文なしでBuilderを使用する方法はありますか?ブロックに依存するのではなく、プログラムで「現在のスタンザを閉じる」ように指示する方法はありますか?