Ngnix Upload Awesomeness pt2
Aug 20th, 2008 by nahum
Eek, a week’s gone by without a blog entry. The joys of paid work I guess. Anyways, I have some further comments about the nginx upload module that I previously blogged about.
I can report back that it’s working a treat, once I figured myself around it’s undocumented behaviour. I’m running it on two sites with Nginx 0.7.10 and 0.7.9. Additionally the ‘dummy’ location doesn’t need to be defined at all, even though the upload location references it. I thought it was, but apparently not.
Something that astute readers will note is that what I’ve talked about doing won’t work unless everywhere the app is used, including developer machines, is through nginx with the upload module. Basically you can’t talk directly to the application instance while your developing because the action receiving the upload won’t be expecting the file in the request:
def upload_completed if params['upload_data.name'] && params['upload_data.path'] # do something with the file end redirect_to :action => 'upload' end
You can get around this by setting up a before_filter which detects if that’s the case and and simulates what the upload module does:
require 'tempfile' before_filter :extract_upload, :only => [:upload_complete] private def extract_upload if !params['upload_data.path'] && params[:upload_data] tmp_file = Tempfile.new(params[:upload_data].original_filename) File.open(tmpfile.path, "w" ) { |f| f.write(params[:upload_data].read) } params['upload_data.path'] = tmpfile.path params['upload_data.name'] = params[:upload_data].original_filename end end
Easy as. What if you’re using something like attachment_fu where you would normally pass the file data from the params hash through to the model as it’s created? If you follow this article about LocalFile then it’ll still work a treat for you:
def upload_completed if params['upload_data.name'] && params['upload_data.path'] # pass to attachment_fu using thirdparty LocalFile class: # http://benr75.com/articles/2008/01/04/attachment_fu-now-with-local-file-fu current_user.uploads.create({:uploaded_data => LocalFile.new(params['uploaded_data.path'])}) end redirect_to :action => 'upload' end
Not sure if it works with Paperclip though, but I will be testing this at some point, so I’ll report back what I find.
There you have it, that should work nicely for you now. If it doesn’t drop me a note and I’ll see if I can help.
