Forms with multiple types of fields

Archived from the Transloadit support forum. Originally posted on August 25, 2012; details may be outdated, see our docs for current behavior. Original thread

Hello,

I’m interested in using your service to overcome a timeout problem my users experience when trying to upload large image files to my app on Heroku.

But the forms that users can use to upload avatars and other images currently have other types of fields on them like name and address etc, and
I am not sure if your service can handle this. For example, are the fields returned in the redirect along with the upload results so that they too can be persisted to the database? If they are, do you use https to protect the information?

If it’s not possible to use forms with a mix of field types, then I am thinking that I could use your JQuery plug in to upload the file, stash the results in a hidden field on my form and then the user can submit the form in the usual way. Of course, I would configure the plug in to not auto-submit the form. Would this be possible?

Thanks,
Lee.

For example, are the fields returned in the redirect along with the upload results so that they too can be persisted to the database?

So if you’re using our plugin, it will only send the files to our service. Once they are uploaded, it will take the response from our service and submit it along with your other form fields (except for the file ones) to your server. Your users input values that are not files would never be send to our server, only to your server directly. This is the default way our system works.

If you’re not using JavaScript / our plugin, things can become a little more tricky, let me know if that’s what you were planning on.

If they are, do you use https to protect the information?

Yes, https is available (just include our plugin via https and make sure your redirect_url is https).

Let me know if this makes sense.

Hi Felix,

Thanks for getting back to me.

Since writing to you I’ve been able to get your service nicely integrated into my Rails app which runs on Heroku :slight_smile: I am using your plugin (and Rails gem) to achieve the following:

1 Upload image to your service for resizing
2 (on form submission) Fetch resized image from your service and store on
S3 via Carrierwave/fog

This has allowed me to overcome Heroku timeouts when users try to upload large images. So I’m very pleased and will be upgrading my account to a paid plan.

I did spend a lot of time trying to creating a Ruby Tempfile object (for the fetched image) so that I could merge the file (and its metadata) into the Rails params (as if it was submitted inline within the form). Here’s a code snippet:

file_url = params[:transloadit][:results][template_key].first[:url]
filename = params[:transloadit][:results][template_key].first[:name]
mime_type = params[:transloadit][:results][template_key].first[:mime]

 uploaded_file = ActionDispatch::Http::UploadedFile.new(
{ tempfile: open(file_url),
filename: filename,
type: mime_type
}
)

I discovered that you cannot rely on open(file-url) to always return a
Tempfile. It can return a String if the file size is small.

So I had to workaround this with the following:

OpenURI::Buffer.send :remove_const, ‘StringMax’ if
OpenURI::Buffer.const_defined?(‘StringMax’)
OpenURI::Buffer.const_set ‘StringMax’, 0

Thought I’d share the above with you in case anyone else hits a similar problem.

Regards,
Lee.

Thanks, do you think those code snippets should be integrated into our rails SDK in one way or another?

Hard to say. If I were starting from scratch, I would have just used your service along with S3 as it would do everything I needed (and more). But my site has been using carrierwave for some time now and I wanted to avoid swapping it out completely at this time (though I might in the near future). I suspect there are other customers who’d benefit from this approach. So might be worth including in your docs and/or your SDK.

The code snippets I shared allowed me to integrate your service into carrierwave seamlessly and with minimal impact on my existing controller code and no impact on my models. For example, I only needed to add the following to the affected controllers:

def create
if file_uploaded?
params[:post].merge!(:photo => uploaded_file(:resize_to_540))
end
… existing code
end

file_uploaded? and file_uploaded are methods I added to
application_controller:

def file_uploaded?
params[:transloadit].try(:fetch, :results, {}).present?
end

def uploaded_file(template_key)

file_url = params[:transloadit][:results][template_key].first[:url]
filename = params[:transloadit][:results][template_key].first[:name]
mime_type = params[:transloadit][:results][template_key].first[:mime]

# Ensure open(file-url) returns Tempfile and not String
OpenURI::Buffer.send :remove_const, ‘StringMax’ if
OpenURI::Buffer.const_defined?(‘StringMax’)
OpenURI::Buffer.const_set ‘StringMax’, 0
uploaded_file = ActionDispatch::Http::UploadedFile.new(
{ tempfile: open(file_url),
filename: filename,
type: mime_type
}
)
OpenURI::Buffer.send :remove_const, ‘StringMax’
OpenURI::Buffer.const_set ‘StringMax’, 10240

uploaded_file
end

By way of example, I uploaded a 2.3Mb image yesterday which, after resizing to 540x540, meant that open(file_url) would only need to fetch a file of
100Kb or so. For your information, I still use carrierwave to produce smaller versions of images (so as to minimise impact on my app).

Hope this helps.

Lee.

Hi Lee,

ah, I didn’t catch your reference to carrierwave in your initial comment, sorry about that.

Yes, better integration with other gems used by people for file uploading is one our agenda, but it will take us a bit to get there. So I was wondering if you’d mind me making this ticket public, so others have a chance to come across your advise when they google “transloadit carrierwave” ?

Cheers,
Felix

Sure thing, Felix. Please go ahead and make it public.

Cheers,
Lee

Thanks! Made it public and closing it for now.