Ajax File Upload in Rails using Dropzone and Carrierwave
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!