【Ruby on Rails4】dropzone.jsを使ってファイルアップロード・削除機能を実装

はじめに

rails環境でdropzone.jsを導入してファイルアップロード機能を実装する

概要

まずはデモ画像

f:id:watarisein:20160610130046p:plain

実際の動作は以下から

http://workshops.ddns.net/albums/upload_photos/4160

dropzoneの説明は本家ページを参照

Dropzone.js

構成

Album has many Pictureの関係

事前準備

Gemfileに以下を追加してbundle install

gem 'dropzonejs-rails'

手順

アップロードフォームを作る

app/views/albums/upload_photos.html.erb
<h1>画像アップロード</h1>

<%= render partial: 'upload_photos_form',  locals: { album_id: @album_id } %>

<br>
<%= link_to 'アルバムへ戻る', {:controller => 'albums',:action => 'show_pictures'}, {:class => 'btn btn-default btn-sm'} %>
<%= link_to 'トップページに戻る',  {:controller => 'top_pages',:action => 'home'}, {:class => 'btn btn-default btn-sm'} %>

アップロードフォームを部分テンプレートとして作成。

app/views/albums/_upload_photos_form.html.erb
<%= stylesheet_link_tag 'dropzone/basic' %>
<%= stylesheet_link_tag 'dropzone/dropzone' %>
<style>
.dropzone {
  border: 2px dashed #b4bcc2;
  @include border-radius(4px);

  .dz-message {
    font-size: 16px;
    text-align: center;
    margin: 0
  }
}
</style>

<%= form_tag(@albums, class: 'dropzone', id: 'upload-dropzone', remote: true, authenticity_token: true) do %>
  <div class="fallback">
    <%= file_field_tag('picture[image]') %>
  </div>
<% end %>

<%= javascript_include_tag 'dropzone' %>

dropzoneの動作を定義するjsを編集する。

app/assets/javascripts/dropzone.js
Dropzone.autoDiscover = false;

var headlineDropzone = new Dropzone("#upload-dropzone", {

  url: "/api/v1/albums/upload_photo", // You can override url of form in here.

  params: {
    album_id: <%= album_id %>,
  },

  maxFilesize: 5, // in MB

  addRemoveLinks: true,

  parallelUploads: 2,

  acceptedFiles:'.jpg, .png, .jpeg, .gif', // type of files

  init: function(){

    this.on('addedfile', function(file) {

      // Called when a file is added to the list.

    });

    this.on('sending', function(file, xhr, formData) {

      // Called just before each file is sent.

    });

    //json is picture object whitch server return
    this.on('success', function(file, json) {
      // Called when file uploaded successfully.
      console.log(json);
      $(file.previewTemplate).find('.dz-remove').attr('id', json.id);
    });

  },

 removedfile: function(file){
     // grap the id of the uploaded file we set earlier
     var id = $(file.previewTemplate).find('.dz-remove').attr('id');
     var delete_file = file
     // make a DELETE ajax request to delete the file
     $.ajax({
         type: 'DELETE',
         url: '/api/v1/pictures/' + id,
         success: function(res){
           $(delete_file.previewTemplate).fadeOut();
         }
     });
 }

});

apiのルートを設定

  namespace :api, { format: 'json' } do
    namespace :v1 do
      post "albums/upload_photo"
      resources :pictures
    end
  end

画像を保存する処理を実装

app/controllers/api/v1/albums_controller.rb
  def upload_photo
    @picture = Picture.create(
                  #パラメーターを設定
               )
picture.save!

    render status: 200, json: @picture, nothing: true
   end

画像を削除する処理を実装

app/controllers/api/v1/pictures_controller.rb
  def destroy
    @picture = Picture.find(params[:id])
    @picture.destroy
    respond_to do |format|
      format.html
      format.json { render :json =>  true }
    end
  end

これで完成