概要
Active Storageにはデフォルトのバリデーションがないため、自前でバリデーション設定をした時のことを備忘録として記録します。
環境
・ruby '2.5.7'
・rails '5.2.3'
過程
1.準備
Active Storageを導入するために以下のコマンドを実行します。
$ rails active_storage:install
以下の2つのテーブルを作成するマイグレーションファイルが作成されます。
・active_storage_attachments
・active_storage_blobs
rails db:migrateしてテーブルを作成します。
$ rails db:migrate
2.モデルへの関連付け
モデルへの関連付けをしていきます。
ここでは、Userモデルに複数のプロフィール画像を設定する場合とします。
class User < ApplicationRecord
has_many_attached :avatars
end
:avatars
はファイルの呼び名で、:photos
、:images
などファイルの用途に合わせて好きなものが指定出来ます。Userモデルに画像用のカラムを用意する必要はありません。
3.バリデーションの設定
Userモデルにバリデーションの設定をしていきます。
ここでは、次の3つの設定をしていきます。
・avatar_type
アップロード出来るファイル形式を指定します。
・avatar_size
アップロード出来る1ファイルの大きさ(容量)を指定します。
・avatar_length
アップロード出来るファイルの数を指定します。
class User < ApplicationRecord
(省略)
validate :avatar_type, :avatar_size, :avatar_length
private
def avatar_type
avatars.each do |avatar|
if !avatar.blob.content_type.in?(%('image/jpeg image/png'))
avatar.purge
errors.add(:avatars, 'はjpegまたはpng形式でアップロードしてください')
end
end
end
def avatar_size
avatars.each do |avatar|
if avatar.blob.byte_size > 5.megabytes
avatar.purge
errors.add(:avatars, "は1つのファイル5MB以内にしてください")
end
end
end
def avatar_length
if avatars.length > 4
avatars.purge
errors.add(:avatars, "は4枚以内にしてください")
end
end
end
ちなみに、avatars.purge
で一時データを削除しています。
他の入力項目でバリデーションエラーが起きてしまうと、Rails5.2系〜6.0系以前ではモデルのインスタンスのattributeに代入した時点で、アップロードしたファイルがストレージに保存されてしまい、その結果として、blobにエラー用の一時データが溜まってしまう可能性があるためです。
(ただ、Rails6.0へのアップデートでActive Storageの機能変更があり、saveメソッドが実行された後に、ストレージに保存される仕様に変更されたので、6.0以降であれば不要です)
結果
参考
ActiveStorageがCarrierWaveの代用として使えるか考える
Rails5 Active Storageを使って画像アップロード機能を実装する