Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the HTML5 multiple file upload field map to a nested model in Rails 3?

I'm trying to use the HTML5 multiple attribute on a file field in a nested form.

The models are as follows:

class Album < ActiveRecord::Base

  has_many :album_images
  has_many :images, :through => :album_images

  accepts_nested_attributes_for :images

end

class Image < ActiveRecord::Base

  has_many :album_images
  has_many :albums, :through => :album_images

  mount_uploader :filename, ImageUploader

  validates_presence_of :filename

end

The view:

  <%= semantic_form_for @album, :url => upload_path do |f| %>
    <%= f.inputs do %>
      <%= f.input :name, :label => 'Album title' %>
    <% end %>

    <%= f.input :images, :as => :file, :input_html => {:multiple => true} %>

    <%= f.buttons do %>
      <%= f.commit_button 'Upload' %>
    <% end %>
  <% end %>

When I use for the file field:

<%= f.input :images, :as => :file, :input_html => {:multiple => true} %>

I get:

<input id="album_images" multiple="multiple" name="album[images][]" type="file">

Which doesn't doesn't seem right since I think I want to set the filename on the object directly, but I'm not sure about this. When I try to upload with this field, the incoming params look like:

 "album"=>{"name"=>"2011-01-09", "images"=>["IMG_0052.JPG", "IMG_0053.JPG", "IMG_0054.JPG", "IMG_0055.JPG"]}

However, I get the following error:

ActiveRecord::AssociationTypeMismatch (Image(#2157004660) expected, got String(#2151988680)):

OK, that error is probably due to the fact that it just received a filename and not an image object. So instead, I use for the file field:

<%= f.input :images, :as => :file, :input_html => {:multiple => true, :name => 'album[images][][filename]'} %>

for which Formtastic generates:

<input id="album_images" multiple="multiple" name="album[images][][filename]" type="file">

The incoming params look like:

"album"=>{"name"=>"2011-01-09", "images"=>[{"filename"=>"IMG_0052.JPG"}, {"filename"=>"IMG_0053.JPG"}, {"filename"=>"IMG_0055.JPG"}]}

But then I get this error:

Image(#2153868680) expected, got ActiveSupport::HashWithIndifferentAccess(#2158892780)

So how does one go about setting up this multiple file input filed mapping in Rails?

Thanks.

like image 359
cotopaxi Avatar asked Jan 10 '11 05:01

cotopaxi


1 Answers

You need to include :html => { :multipart => true } in your form_for (or in your case semantic_form_for) call so that your <form> tag is set to support file uploads.

Then revert back to your original syntax for f.input and you should be right then.

like image 80
smathy Avatar answered Sep 20 '22 18:09

smathy