A Weekend on Rails - Day Two

Posted by blackrat on November 19, 2006

Last time, I built a standard scaffolded Rails application with a modified database, controller (admin) controlling a model named programme. The next step is to add a view and import mechanism. The standard scaffold mechanism uses a list.rhtml as the entry point, so we will create one of these to override the scaffold, and display a list of the current programmes, along with the import button.

<h1>Listing programmes</h1>
  <table>
    <tr>
      <% for column in Programme.content_columns %>
        <th><%= column.human_name %></th>
      <% end %>
    </tr>
    <% for programme in @programmes %>
      <tr>
        <% for column in Programme.content_columns %>
          <td><%=h programme.send(column.name) %></td>
        <% end %>
      </tr>
    <% end %>
  </table>
  <%= link_to ‘Previous page’, { :page => @programme_pages.current.previous } if @programme_pages.current.previous %>
  <%= link_to ‘Next page’, { :page => @programme_pages.current.next } if @programme_pages.current.next %><br />
  <%= link_to ‘Import XML’, :action => ‘load_xml’ %>

and add a new “load_xml.rhtml” template

<h1>Load XML<h1>
<%= form_tag({ :action=> ‘import_xml’}, {multipart => true }) %>
<%= file_field :document, :file %>
<%= submit_tag ‘Import’ %>
<%= end_form_tag ‘Import’ %>
<%= link_to ‘Back’, :action => ‘list’ %>

Ok.So much for the easy part. We need to add an entry to the controllerfor the ‘import_xml’ action that has just been declared. This will haveaccess to the embedded file uploaded using the file_field :document,:file instruction.

The decision to make the database table columns have exactly the same namesas the XML attributes allows for the following code to populate thedatabase. So the final app/controller/admin_controller.rb looks like:

class AdminController << ApplicationControllerscaffold :programme
  def import_xml
    require ‘rexml/document’
    file=params[:document][:file]
    doc=REXML::Document.new(file.read)
    doc.root.each_element(’//programme’) do |p|
      if not Programme.find(:first, :conditions => [ “name=?”, p.attibutes[:name] ]) then
        @programme=Programme.new
        @programme.update_attributes(p.attributes)
      end
    end
    redirect_to :action => ‘list’
  end
end

Ok. That’s it for now. I’ve scratched the rails surface and learnt something new. More discoveries soon.

Trackbacks

Use this link to trackback from your own site.

Comments

You must be logged in to leave a response.