Let's start with the basics. Suppose you have an action like this:
def upload_to_meAssume that the_file is an item uploaded from a form in a file input field. Now Rails will automatically process all this for you and handle the temp file creation and all that. However one optimization Rails will do is if the file is smaller than 10kB, it just sticks it in an UploadedStringIO object which is not a file - so there is no temporary file.
file = params[:the_file]
end
Let's expand our action. We want to open up this file (assume it is a .zip) and take a peek at the contents:
Zip::ZipFile.open(file.path) do |zip|The ZipFile object only accepts a filename. There is no way for you to pass in anything else, like say an IO object. So we have a predicament. The UploadedStringIO object we have is raw zipped data, but we can't actually unzip it because it is not a file.
end
What's the solution? It's ugly, but turn it into a file:
if file.is_a?(UploadedStringIO)We use Ruby's Tempfile object, which stores things in a temporary folder (by default on Ubuntu it appears to be /tmp) and is designed to be thread-safe so that you don't have to worry about people clobbering each other's temp files.
temp_file = Tempfile.new("some_temp_name")
temp_file.write file.read
file = temp_file
temp_file.close
end
# now file is a File object and can be treated as such
I suppose since I have access to both Rails' code and the Zip gem's code, I could probably hack this stuff to make it work properly without being ugly, but this small fix should be enough for now. A good optimization would be to add something to ZipFile so that it can accept a IO object and not just a filename.
4 comments:
Just to let you know, your post helped me realize that I can pass ImageScience the Rails Temp File directly.
ImageScience.with_image(uploaded_image.path) do |img|
Glad to be of help! But remember the little gotcha I mentioned, if the file is small then Rails will not actually save it to a file. The IO class doesn't actually have a path method so your code will crash on files under 10kb.
thank you! i was having this exact same problem with my site. cheers to your helpful code snippet! i was starting to get stressed out ha ha but now i'm happy again :-) i owe you!
Thanks for the help
I were looking for how to write the UploadedStringIO data into a file, It was so easy just run "read", but rails documentation is so poor, sometimes you dont find nothing.
Post a Comment