How to Upload to Carrierwave with JavaScript

Carrierwave makes it easy to attach files to Rails models, but all the uploading magic operates synchronously. If you're using Backbone and want to keep model updates asynchronous, it may seem like you're out of luck.

You're not. The new XMLHttpRequest, which you may know better as AJAX, supports an interface called FormData. This uses the same format as a synchronous form submitted with its type set to multipart/form-data, which is what enables file uploads in a regular, synchronous form. Make sure your target browsers support FormData.

Say you have a User model with a Carrierwave field called :avatar. The update action of your RESTful controller might look like this:

The beauty of Carrierwave is that the above code just works. You don't have to manage the file upload separately from any other model attribute.

Now let's say your view has a file upload field with the id "avatar." This JavaScript snippet, to be run inside a Backbone view, will send that file to your controller asynchronously:

Note that the string we appended to formData, "user[avatar]," corresponds to how your controller expects your params. Doing this frees you from changing your controller whatsoever.

Credit to this stackoverflow post for helping me get the correct $.ajax properties.