nobu blog

プログラミングやゲームの話など。

*



ActiveStorageを使用した画像アップロードとプレビュー機能(Ruby on Rails)

      2020/05/06

概要

Ruby on Railsで5から追加されたActiveStorageを使ったファイルアップロード機能を実装した時のメモ

前提

Mac OS 10.15.4
予めRailsの一式はインストール済
Ruby 2.6.3p62
Rails 6.0.2.2

手順

インストール

下記のコマンドでActiveStorageのインストールとDBのマイグレーションを実施する。
(ActiveStorageをインストールすると新しいテーブルが追加されるため、マイグレーションが必要となる。)

AWSなどを使う場合にはこの後、設定が必要だがデフォルトのサーバのローカールストレージのまま使用する。

モデル設定

任意のモデルを作成する
rails g model Article title:string

作成したモデルにファイルアップロード用のフィールドを追加する。
“has_one_attached: フィールド名”で定義する。
複数のファイルをアップロードしたい場合は、has_many_attachedにする。

追加後にDBのマイグレーションを実行する。
rails db:migrate

コントローラ設定

コントローラを作成する。
rails g controller Article

ストロングパラメータ(article_params)に画像用のフィールドを忘れずに追加する事。
destroyでデータ削除時には、purgeでファイル自体を削除する。
あとは特段意識せずに、通常と同じように実装。

View設定

コントローラに対応するビューを作成する。
新規作成時のViewを一例として取り上げる。

attachedで画像が以前にアップロード済かどうかを判断可能。
アップロード済の場合はimage_tagヘルパーで画像を表示する。

下記のように一度確定後に、再度編集を行うと下記のように以前の画像が表示される。

View設定(プレビュー)

現在の実装では確定後の画像しか表示できないため、ファイル選択後にプレビューできるようにする。
ブラウザ側での処理となるのでJS側に処理を追加する。

jQueryの追加

DOM操作をしやすいようにjQueryをインストールして使う。

yarnでインストール
yarn add jquery

jsをバンドルできるように設定する。

app/assets/javascripts/application.js

// 追加
require(‘jquery’)

webpackに追加

config/webpack/environment.js

実装

ファイルダイアログで画像選択時に画像を追加する処理を定義する。
先ほどのフォームを編集する。

下記のようなjsを定義する。
注意点として、”article_title_image”は
<%= form.file_field :title_image %>
で自動で付与されるidなので使用するフィールド名に合わせて変更する。

その他

画像のリサイズ

アップロード後の画像をそのまま使うのではなく、リサイズや加工する事も可能。

GemFileの下記がデフォルトではコメントアウトされているので、外してbundle installを行う。
# Use Active Storage variant
gem ‘image_processing’, ‘~> 1.2’

ImageMagickがインストールされていない環境で使用する場合、brewやapt-getなどでインストールしておく。

表示時にvariantメソッドを呼び出して、表示サイズなどを指定する事でリサイズ後の画像が表示されます。
processedをつける事で、既に変換済の画像がある場合には再利用するのでキャッシュが効くようになり早くなります。

<%= image_tag article.title_image.variant(resize_to_fill: [300, 300]).processed %>

ファイルの削除

画像ファイルの差し替え時などには削除されずにファイルは残るでの下記の処理を定期的に実行する事で紐付けできていないファイルも消す事が可能な模様。
(まだ未検証)
ActiveStorage::Blob.unattached.find_each(&:purge)

バリデーション

下記のようにモデル内にバリデーションを実施する事でファイルのチェックも可能。
下記はファイルサイズのチェックを実施。

まとめ

駆け足だが、ActiveStorageでのファイルアップロード方法を紹介した。
DB処理としてのActiveRecordは、SQLを隠蔽するため独自のルールを多く覚えないといけないが、
ActiveStorageはシンプルでファイルのアップロード操作が使いやすく隠蔽されていて素晴らしいと感じました。

 - Javascript, Ruby on Rails