Ruby on Rails’s handling of uploaded files
Every framework has its own insanities, and Ruby on Rails (and Ruby!) is no different.
I’m writing an application which handles image uploads. Rail’s API documentation doesn’t mention anywhere what the type of an uploaded file parameter is. The book “Rails Solutions” doesn’t mention it either, but it seems to have the same interface as the IO class. At first, I thought that the type is Tempfile (I found that out with some print statements). But that’s not entirely true:
- Files smaller than some specific size (I don’t know what the threshold is) will be of the type StringIO.
- Larger files will be of the type Tempfile.
Insanity #1: For some reason, Rails doesn’t unlink the Tempfile object after the HTTP request has been processed, so unless I unlink it manually the file will stay on the hard disk!
Insanity #2: Although StringIO and Tempfile have the same methods as the IO class, they aren’t derived from IO, or even have IO as mixin! As a result, is_a?(IO) will return false.
I spent an hour debugging my application because of this. RMagick accepts either a filename or an IO object to read the image from. The problem is, RMagick doesn’t recognize the variable for the uploaded file as an IO object. So I had to write code for 2 cases: if the uploaded file is a Tempfile, pass the tempfile’s path to RMagick. If not, create a new Tempfile, write the uploaded file’s data to that tempfile, and pass the tempfile’s path name to RMagick.
Insanity #3: According to Rails Solutions, the uploaded file has a method ‘content_type’, which isn’t part of Tempfile or part of StringIO. Again, this isn’t documented in the Rails API documentation (ActionController::TestUploadedFile mentions the method, but it’s not exactly an intuitive place to look in). Rails seems to magically add this method to the StringIO and Tempfile classes.
I do hope that they improve the API docs.

Benny said,
April 9, 2007 @ 11:52 pm
thanks for this post! i JUST ran into this problem and wasn’t sure how to fix it.
Jeroen van Doorn » Blog Archive » Temporary insanity said,
April 17, 2007 @ 8:51 am
[...] found a great post about Rails’ handling of temporary files with file uploads. It was driving me insane, but this post [...]
Sean Cannon said,
June 25, 2008 @ 4:09 am
Any idea how to go about getting the original_filename from a small file that came back as StringIO?
‘Cause that’s important…