ruby on rails - Multi file uploads with attachment_fu

by: workr77 on September 05 2008

This tutorial will cover multi file uploads using ruby and rails and the plugin attachment_fu by technoweenie. The code used here is a direct copy from the mephisto file upload function. For one of my web sites, I needed a way to allow forms to have a “add another” image or attachment link and have the link create a dynamic amount of file upload fields. So far everything works well. Hope you enjoy this tutorial.

Step 1: Create your rails form, create.rhtml

Here is the basic form that I used..


 <% form_for :pic, :url => { :action => 'save' }, :html => 
{ :multipart => true } do |f| -%>

....           

<label for="contact_message_1" class="left">Photo:</label>

        <%= file_field_tag 'asset_data[]', :id => 'asset_data_1' %> 

    <div id="block-div"></div>

<%= link_to_remote 'Add another file', :url => { :action => 'new_attachment'}, 
:method=>:post%>

    <input type="submit" name="submit" id="submit_1"  /> 
</p>
        <% end -%> 

Step 2: Create the RJS file to add file upload field

here is the rjs file to create the dynamic file upload field. I called it new_attachment.rjs

page.insert_html :bottom, "block-div", :partial => 'add_attachment'

Here is the partial that is called

<p><label for="contact_message_1" class="left">Photo:</label>

<ul id="filefields">

 <%= file_field_tag 'asset_data[]', :id => 'asset_data_1' %>
</ul>

Step 3: Saving the multiple files

Here is the save method


  def save
    ...
    if @post.save

      @assets = []
      params[:asset] ||= {} ; params[:asset_data] ||= []
      params[:asset].delete(:title) if params[:asset_data].size > 1
      params[:asset_data].each do |file|

        if file != ""     
     @assets << 
@post.build(params[:asset].merge(:uploaded_data => file))
       end

    Post.transaction { @assets.each &:save! }

    end

    end

  end

The finished product should look like this

here is the basic form that the multi upload field should look like.

From my understanding of the code, http puts the files in a hash. Once it gets over to rails, we simply step through the hash and build each photo into the model.

Quick note, if your on a shared host, multi large files may not complete the saving process. I think that when uploading to amazon s3, and if the server is under some kind of load, there comes a timeout in the process.