Say we need some XML files that represent data currently stored in a database. To make it simple, our desired file will use the table name pluralized as the parent element, and contain nested singular elements, one for each record in the database. Within the record elements, each field name is an element, and the value of that field is the text value of that element.
Let's generate this file from Rake.<?xml version="1.0" encoding="UTF-8"?>
<bonds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="bonds.xsd">
<bond>
<issuer>GENERAL MOTORS CORP</issuer>
<rate>0.072</rate>
<coupon>Fixed</coupon>
<maturity>1/15/2011</maturity>
<type>US Corporate Debentures</type>
<price>19.5</price>
<yield>1.29582</yield>
<callable>true</callable>
<frequency>Semi-Annual</frequency>
<first_payment>7/15/2001</first_payment>
</bond>
<bond>
<issuer>FEDERAL NATL MTG ASSN</issuer>
<rate>0.045</rate>
<coupon>Variable</coupon>
<maturity>2/17/2012</maturity>
<type>US Agency Retail Note</type>
<price></price>
<yield></yield>
<callable>Yes</callable>
<frequency>Semi-Annual</frequency>
<first_payment>2/17/2005</first_payment>
</bond>
</bonds>
1. Generate a new Rails application by typing rails code_generator (or whatever you wish to call your helper application)
2. Change RAILS_ROOT/config/database.yml to point to your applications DB
development:
adapter: sqlite3
database: db/development.sqlite3
timeout: 5000
3. Create a file named something like generator.rb in RAILS_ROOT/lib/tasks
4. Require ERB at the top of this file.
require 'erb'
5. Add a method to send the contents of a table to an ERB template named table.type.erb . Notice the second to last line of the method below. It's where we pass the binding method to ERB. this will make all our variables and methods available to the ERB template we create later, including the dataset variable and the table variable.
def process_erb(type,table)
# Grab our ERB template
template = ERB.new(IO.readlines("lib/tasks/table.#{type}.erb").to_s
# Use Active Record to get our dataset from the DB
dataset = ActiveRecord::Base.connection.execute("select * from #{table.underscore}")
# Create a new file for the ERB output
file_name = "#{file_name}.#{type}"
f = File.new("#{file_name}",'w')
# Write the ERB output to the new file:
f.puts(template.result(binding))
f.close
end
6 . Add a rake task to call our method to create an XML file.
TABLE = ENV['TABLE']
task :create_xml => [:environment] do
process_erb("xml",TABLE)
end
7. All we need is the ERB template named table.xml.erb We write this taking advantage of the dataset and table variables available to us from the ruby binding.
8. Our method expects a table name at the command line , so we'll call it with
<<%=table.underscore.pluralize%>>
<% dataset.each{|row| %>
<<%=table.underscore.pluralize%>>
<% row.each{ |k,v| %>
<<%=k%>><%=v%></<%=k%>>
<% } %>
</<%=table%>>
<% } %>
</<%= table.underscore.pluralize %>>
rake create_xml TABLE=bond
The result is a bonds.xml file with our desired data!
9. Notice how our template name contains our desired file type, xml, then our method takes this as a parameter. How easy will it be now to create a table.java.erb template, and call it? How about a template called table.php.erb ?
10. How about running this generator from jRuby to access an Oracle database?
development:
adapter: jdbc
driver: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@oracle.apptrain.com:1521:xe
username: test



