This weekend I finished off my own little Hello World mini-CMS, that I wrote in order to learn Ruby on Rails. The last part meant adding an image uploader, that would allow users attach an image to a page. There are two popular image uploader plugins for Rails: The slightly older, more complicated and feature-rich attachment_fu and the more nimble paperclip. Paperclip seems to have the limitation that it only allows one attachment per model instance. On the other hand, you don’t need to create a separate model for your attachments. For this project I absolutely needed multiple attachment per page so I went with attachment_fu. I also didn’t want a separate form for uploading images, which would mean having to later associated the image with a page - I wanted to be able to upload from the page’s editing form. This case doesn’t seem to be covered well in attachment_fu’s documentation, so this is an attempt of closing this gap.
Installing the requirements
You will have to install an image processor. This is described in many other blog posts so I won’t regurgitate it here. I personally went with ImageMagick and rmagick. Seems to work fine. Once you’ve done that you obviously have to install the plugin itself with: ./script/plugin install http://github.com/technoweenie/attachment_fu.git
Edit: Rails 3 has been released shortly after I wrote this post and this plugin doesn’t work anymore. However there is an alternative branch on Github.
Setting up the models
You will need to use a separate model to store all the attachment meta data. I have called mine Photo but that name is arbitrary - call it what you want. So, lets build a migration:
Controller & form
A lot of tutorials say that you should set up your own controller for the image upload. But that would mean that you have to use a separate form for uploading images. What I wanted to do was to also use the ordinary page editing form for image uploads. So, I found a forum post that put me on the right track and after a bit more of trial and error I figured it out. First, you need to slightly edit the form where you want to upload the image from. It needs to be a multipart form and you need to add a file field. With the
file_field_tag part you are telling Rails that it should not put the photo attachment in the main form object but rather create a second hash called
photo. In the controller we will be reading out exactly this hash and store it in the photo model. So, here is the controller code:
I couldn’t find a good tutorial on how this is done so I hope someone wanting to do the same will find this page. Happy coding.