Multiple file upload with: Rails, File_Column plugin and MooTools
| December 18th, 2007Recently, I had to come up with a multiple file upload form that works with the file_column plugin. My site was already using mootools as it’s main JS framework so I wanted to come up with a solution that would be mootools friendly.
Luckily, I found this great mootools plugin that handles multiple file upload in an elegant way, so I decided to start with that as a base.
I had to modify the script, mostly because file_column requires a hidden field for every file field there are in your form. I provided a link to this modified version at the bottom of this post.
Here is a step by step guide to make this work (I am assuming you are familiar with file_column already).
For this example, let’s pretend I have the following models:
- User (my user model)
- UserPicture (a picture uploaded by a user)
My UserPicture model has 2 attributes: user_id and image(the file_column). The relationships are as follow: User has_many UserPictures, and UserPicture belongs_to User
I will use 1 view to allow the user to upload pictures. That view will contain the form with the file fields. This is what the view’s code looks like:
Picture Upload
The important parts are: My file input needs to have the class name as it’s “name” attribute, in this case; user_picture. If your model name is different, change the file input’s name to reflect your model name. Also, if your file_column’s name is NOT “image”, you need to change this line:
$ ‘main_form‘ user_picture3‘[{id}][image]‘truetrue‘[{id}][image_temp]‘ ;
So it reflects your file_column’s name (change both [image] and [image_temp]) so if your file_column’s name is “picture”, this line would become:
$ ‘main_form‘ user_picture3‘[{id}][picture]‘truetrue‘[{id}][picture_temp]‘ ;
What this will do, is to allow users to upload up to 3 pictures (you can change that in the parameters). For every new picture uploaded, the javascript creates a new file field, and a new hidden field, required by file_column, so they will look like this in the generated html:
<input type=”file” name=”[user_picture][x][image]”>
<input type=”hidden” name=”[user_picture][x][image_temp]”>
Where “x” = an incrementing ID (0, 1, 2…)
Next is your controller. In this case, I chose to send the form to “uploadpictures” action of the “users” controller. This is what this controller needs to look like:
params[:user_picture].each do |id, image|
@user_picture = UserPicture.new(image)
@user_picture.user_id = @current_user.id
@user_picture.save
end
end
So basically, for each user_picture in the params, I create a new UserPicture model instance, passing the “image” parameter… For my own needs, I have to track the user_id too so the picture is associated to a user. This could be done with a hidden field in the upload form, in my case, sessions are already taking care of it.
And that’s it basically… all the pictures should be uploaded correctly, following file_column’s directory structure, and inserted in the database.
NOTE: In my example, mootools was included in my layout, so I didn’t need to re-include it, but YOU WILL need to include it BEFORE your include the multiple upload script.
To get it working with my modified version, just replace the .js file with mine, and put it in /public/javascripts.
To get the CSS working, I just copied the code of the .css file and added it to my own stylesheet (it shouldn’t overwrite any of your styles but double check to make sure).
And finally, I placed the image that came with it under /public/images/cross_small.gif
The modified version of the Multiple File Upload script can be found here. I suggest you also download the original version here to get the CSS and image file that comes with it.
I made a Flash multiple file upload applet that includes a rails plugin to make it easy to use. It’s licensed under the LGPL, and is very customizable. It is extensively documented, and usage screencasts are available. Check it out at http://multibitshift.com.
JC
Nice work! Flash multi-upload is definitely sexier!
I’ll probably use it somewhere eventually, and offer my version on the side as a non-flash alternative (for those who *still* don’t have flash installed
)
Thank you for the detailed instructions of multi-file upload using file_column.
Do you know how we can add validation for the total file size of all objects prior to submitting a multi-file upload?
Hello, I´m kind of a newbie with RoR, I built a model where a user can have up to 5 images uploaded which are stored in the same model. I have a view which helps the user edit the information he is adding to his post. In this view I would like the user to be able to change the uploaded images (which up to now can be done without problems) and even delete one or two etc images without having to delete his entire posting.
I´ve been searching for this some days from now and havent found anything. I saw in one forum a guy who tried setting the database filename column for the record to “NULL” or ”” and that did not work for the user so he had to build separate models the pictures, which I don´t want to do unless there is no other option.
I would appreciate any help. Thanks!
Thanks for the time saver. I already had a multi file upload setup, but I needed a clean and efficient script to allow for multiple inputs. Your tutorial provided those very nicely :].
Hey glad my post could be useful to someone!