Ajax file upload with DropezoneJs and Paperclip - Rails
11 May 14
You can check out a
Live Demo of what we will be creating. You can also check out the full source code used to create this tutorial at my github repo
We will start by grabbing DropzoneJs from the
Github Repository. The most important files for this tutorial include:
dropzone.css (in css folder)
spritemap.png and firstname.lastname@example.org (from the images folder)
With that we are ready to plug-in dropzone in our application. I will be creating our application from scratch while trying to keep it as simple as possible.
Lets create a new rails application from our console. Lets name it 'dropzone-rails'. You can give it whichever name you wish.
$ rails new dropzone-rails
To handle the uploading of the images, we will be using the famous and robust
Paperclip Gem which is as an easy file attachment library for Active Record. We then add the gem in our Gemfile and run bundle to install it. I've also added the bootstrap gem to give me some quick styling.
- Copy (spritemap.png and email@example.com ) to our app/assets/images directory of our rails application
Next lets create a model to handle our uploaded images. For my case I will name the model
upload. It can be whatever name you choose to give it. My model will only contain attributes of images which we will add shortly using the paperclip generator. Generating our model....
$ rails g model upload
We then add paperclip attachments to our upload model. To do this, simply run the paperclip generator as so
$ rails g paperclip upload image
If this seems a little bit confusing, check out this awesome
railscast on how to use paperclip. Those to commands create migration files which we can run rake db:migrate to migrate our database and add the respective tables and columns.
The next step is to update the model code. We need to use has_attached_file to tell it the name of the attachment field we specified when we ran the migration. I have also done a couple of validations which you can tweak as you wish
Next up, lets create a controller uploads with the new action which will interact with the user and enable him/her upload images and save them to the database.
$ rails g controller uploads new
With this, it would be a good idea to make the root of our application point to the new action of our uploads controller. We can also add an upload resource to our routes.rb file which will provide several RESTFUL urls.
http://0.0.0.0:3000/ should render the new view of our uploads controller
Its now time to add our Dropzone goodness to this page. But before we do, lets first prepare our uploads controller to handle uploaded files.
Now replace the contents of our uploads new view with our upload form. Take note of the '
dropzone' class in our form. All we need to do is assign css class "dropzone" to the form. By default, DropzoneJS will find all forms with class "dropzone" and automatically attach itself to it and creating a file input field and upload files dropped into it to the specified action attribute.
fallback that dropzone will remove if the browser is supported. If the browser isn't supported, Dropzone will not create fallback elements if there is a fallback element already provided.
Next, I will add html mark up to work with bootstrap css to give our application a more appealing feel.
With that done, visiting
http://0.0.0.0:3000/ should give you a good looking page like the one showed below
You may try dragging some image files but you will encounter an error. This is because the name of the file param that gets transferred defaults to
I've use the jQuery plugin Dropzone ships with though you can use the library without jquery
see docs. This is just a tip of the iceberg when it comes to customizing dropzone. Head over to its full documentation and see ways on how to tweak it to suite your needs.
At this stage, we can now try draggin a couple of files on the upload area or by clicking our dropezone and wallah!! if everything worked out all your images should be successfully uploaded like below
Inspecting your application console should also give you something similar to mine
Since writing this tutorial, I recieved alot of requests on how to handle deleting of files from the server when the remove button is clicked. This is actually note very difficult. We need a way to uniquely identify the file to be deleted. To do this, when our uploaded file is successfully uploaded we will return the id of the uploaded file to dropezone and we will use this later when deleting the file. Also as you have guessed we also need a
destroy action to our uploads controller.
This destroy action is fairly standard, since we don't need any redirection, we just render a json response with a message that the file was successfully deleted.
Next up, we need to edit our
uploads.js file. To do this, dropzonejs has a success function that fires when the file has been uploaded successfully. We tap into this function and after the file is successfully uploaded we will give our "remove file" button the id of the uploaded file we earlier returned in our controller.
Dropezonejs has another method
removedfile which gets called whenever a file is removed from the list. We will listen to this and delete the file from our server through a DELETE ajax call.
Hopefully this simple tutorial helped you with your development. If you have questions, do leave a comment below to let me know. Thanks for reading! ;-)