vue-dropzone × Active Storage で画像アップロード
実装したい機能
vue-dropzone × Active Storageを使って、画像を添付したらDBへアップロードされる機能を作成したい
環境
- フロント:nuxt
- バックエンド:Rails
アジェンダ
画像アップロード/フロント側
vue-dropzone
を使って実装する。
vue-dropzone導入方法
- インストール
yarn add vue2-dropzone
- 対象のcomponentにimport
import vue2Dropzone from 'vue2-dropzone' import 'vue2-dropzone/dist/vue2Dropzone.min.css'
- componentsに定義
export default { name: 'app', components: { vueDropzone: vue2Dropzone },
参考
実装
<vue-dropzone id="dropzone" :options="dropzoneOptions" @vdropzone-success="successMethod" > </vue-dropzone>
各項目について
id
- 書かないと警告が出たため必須
options
画像添付時の動作を指定可能。ここで画像保存用のエンドポイントを叩く
data: function () { return { dropzoneOptions: { url: `${process.env.API_BASE_URL}/users/1`, thumbnailWidth: 150, maxFilesize: 0.5, paramName: 'image', method: 'put', } } },
url
- APIのエンドポイントを指定可能。
- 今回は元々あるuserレコードに
put
で画像を追加する
method
- デフォルトはpostでputに変更する事も可能。
- vue内のmethodを指定して呼び出す事も可能だが、画像添付時ではなく読み込み時に呼び出されるため、保存には不向き?。
paramName
- パラメータ名を指定可能。
headers
- ヘッダーを指定可能。今回は未使用だが、認証を使用している場合は使える。
maxFilesize
- 添付画像の最大サイズ(MB)で指定する
maxFilesize
- 添付画像の最大サイズ(MB)で指定する
thumbnailWidth
- サムネイル画像の横幅
@vdropzone-success
- 画像の添付に成功した際に呼び出す処理を指定出来る
- これでDBに保存した画像のURLを取得する。
参照元
画像アップロード/バックエンド側
Active Storageを使って実装する。
Active Storage導入方法
installする
$ rails active_storage:install
テーブルを作る
$ rails db:migrate
active_storage_attachments
、active_storage_blobs
というテーブルを作成される
対象のmodelにActive Storageを定義する
class User < ApplicationRecord has_one_attached :image end
以上。
controllerの実装
- update scaffoldで作ったまんま。
def update if @user.update(user_params) render json: @user else render json: @user.errors, status: :unprocessable_entity end end
- user_params
userモデルで
has_one_attached :image
と指定した事により あたかもimage
カラムがあるかの様に扱う事が可能。
def user_params params.permit(:image) end
アップロードした画像取得/バックエンド側
serializer
でActive Storage
使って画像を取得する仕様にしました。
controllerの実装
scaffoldで作ったまんま特に編集無し。
def set_user @user = User.find(params[:id]) end
def show render json: @user end
serializerの実装
class UserSerializer < ActiveModel::Serializer include Concerns::ImageUrl attributes :id, :image def image url_for(object.image) if object.image.attachment end end
各項目について
ここの意味は?
object.image.attachment
active_storage_blobs
とobject.image.attachment
の2つのテーブルを生成したがそれぞれ
active_storage_blobs
:ファイル名等のメタデータactive_storage_attachments
:画像データそのもの
が格納されている。 それぞれのテーブルにモデルからアクセス出来る。
- active_storage_attachments/アクセス
object.image.attachment
- 結果
#<ActiveStorage::Attachment id: 16, name: "image", record_type: "User", record_id: 1, blob_id: 17, created_at: "2020-03-07 13:23:45">
- active_storage_blobs/アクセス
object.image.blob
- 結果
#<ActiveStorage::Blob id: 17, key: "GF11mXbm3ZiUZtn2zZGVBQWW", filename: "bit201712121505387423.jpg", content_type: "image/jpeg", metadata: {"identified"=>true, "analyzed"=>true}, byte_size: 26108, checksum: "8VqE1O+XAr0PqHGGdxpMIg==", created_at: "2020-03-07 13:23:45">
ここの意味は?
url_for(object.image)
Active Storageで生成したカラムをurl_for
メソッドに入れる事により、URLを生成する事が可能。
Active Storage の概要 - Railsガイド
url_helperを使えるようにするために
一手間必要でしたので、別記事にまとめてます。 Rails url_helperをSerializerで使いたい - hatehate-nazenazeのブログ
参考資料
- vue-dropzone
- Active Storage