Dropzone.jsとRailsでファイルアップローダを作ってみた

久しぶりにブログ書きますね。 いろいろやってるけど、次々と新しいことが振ってきたりで中々纏める時間が無い(という言い訳)

ちょっと仕事でファイルアップローダを作成する必要が出てきて、仕様として複数の画像ファイルを一括でアップロード出来て、 プレビューも表示行うということで、フロント側をどうしようかなって思っていろいろ調べていてDropzone.jsにたどりついたわけです。 試行錯誤しながらやっていたので作業まとめメモ的な内容です。

Dropzone.jsとは

公式サイト Dropzone.js

ざっくりまとめるとこんな機能があるものです。

  • ドラッグドロップ or クリックでファイルアップロード
  • 複数ファイルのアップロードが可能
  • デフォルトでプレビュー機能が付いてる
  • JSON形式でバックエンドのシステムにファイルを送る

環境構築

検証様の環境構築を構築

バックエンド(Rails環境)

  1. Railsアプリを作成
rails new dropzoon_sample --skip-bundle

作成されたRailsアプリに必要なgemを追加します。

2.Gemfileの編集

gem 'carrierwave'
gem 'dropzonejs-rails'

「dropzonejs-rails」ではなく、公式サイトからJSファイルをダウンロードしてassetsに追加しても動作しますが、今回はgemで行ってます。 dropzone.jsの利用方法は変わりません。

3.bundle installを実行

bundle install

4.scafoldでサンプルアプリの雛形を作成

rails g scaffold picture_store picture:string

これでCRUDアプリの雛形が出来ます。

5.carrierwaveのUploaderクラスを作成し、モデルに紐付ける

rails g uploader picture

app/model/picture_store.rb

class PictureStore < ApplicationRecord
  mount_uploader :picture, PictureUploader
end

6.RailsアプリからDropzone.jsを読み込むように設定する app/assets/javascripts/application.js内に以下の内容を追加する

//= require dropzone

app/assets/stylesheets/application.css

 *= require dropzone/basic
 *= require dropzone/dropzone

CSSは必須ではないのですが、サンプルアプリの見た目を良くするために

7.コントローラの編集 createメソッドのインスタンスを作成する部分を以下の様に修正する app/controllers/picture_stores_controller.rb

@picture_store = PictureStore.new({'picture' => params.require(:file)})

8.ビュー部分の編集 app/views/picture_stores/_form.html.erb フォームを編集する

<%= form_tag(picture_stores_path, class: 'dropzone', id: 'upload-dropzone') do %>
  <div class="fallback">
    <%= file_field_tag('attach[file]') %>
  </div>
<% end %>

実行

f:id:hinosita:20161011223237p:plain

まとめ

dropzone.jsは読み込みformタグに所定のid等が設定されているとデフォルトのままでも画像ファイルをセンタするたびに非同期でアップロード処理が動作します。 dropzone.jsを動かすところまでのまとめです。 デフォルト設定を変更して、submitボタンをクリックしてから全ファイルを送ったりファイルの種類やサイズ制限なども容易に可能です。