Ajax File Upload in Rails using Dropzone and Carrierwave

Sudharsanan Muralidharan
Rails, Ember & Beyond
2 min readOct 28, 2015
Image Credits: dropzonejs.com

DropzoneJS is an open source library that provides drag’n’drop file uploads with image previews. For Rails you can use this gem dropzonejs-rails. Add it to your Gemfile.

gem 'dropzonejs-rails'

Add the following to application.js

//= require dropzone

Add the following to application.css

*= require dropzone/dropzone

Refer this http://www.dropzonejs.com/ to add dropzone to your form. Here is a typical example.

<form action="/media-upload" class="dropzone">
<div class="fallback">
<input name="file" type="file" />
</div>
</form>

Rails

Add Carrierwave

If you are not already using carrierwave gem I recommend you add it right away. Carrierwave does all the work for you when it comes to File upload.

gem 'carrierwave'

Refer this link for complete set of instructions Carrierwave.

Media Uploader

rails g uploader media

Generate new Model for Media content

rails g model media file_name:stringclass Media < ActiveRecord::Base
mount_uploader :file_name, MediaUploader
end

Generate new Controller

rails g controller media_contentsclass MediaContentsController < ApplicationController
def create
@media = Media.new(file_name: params[:file])
if @media.save!
respond_to do |format|
format.json{ render :json => @media }
end
end
end
end

Add new route

resources :media_contents, only: [:create]

Form

You can either use form_tag/form_for to generate the form or use plain html as given on dropzone’s website. Either of this will work just fine.

<form action="/media_contents" id="media-dropzone" class="dropzone" enctype="multipart/form-data">
<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>" />
<div class="fallback">
<input name="media" type="file" multiple />
</div>
</form>

Here is the same using form_tag helper.

<%= form_tag '/media_contents', method: :post, class: "dropzone", id: "media-dropzone" do %>
<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>" />
<div class="fallback">
<%= file_field_tag "media", multiple: true%>
</div>
<% end %>

Handling Callbacks using Javascript

Once the form has been submitted the file is stored in specified directory. To get the file details and status we can manually pass data as json from the controller.

respond_to do |format|
format.json{ render :json => @media }
end

In the client side handle the callback.

$(function() {
var mediaDropzone;
mediaDropzone = new Dropzone("#media-dropzone");
return mediaDropzone.on("success", function(file, responseText) {
var imageUrl;
imageUrl = responseText.file_name.url;
});
});

You can also send additional parameters along with that Json from controller and access it in javascript. There are also plenty of options in Dropzone that you can tweak and fiddle around. Dropzone is an awesome plugin you shouldn’t miss.

Checkout the Demo and Source on Github. Happy Hacking!

--

--