- ActiveStorage 5.2
## モデルの定義
こんなモデルがあった時のバリデーションエラーの挙動
class Archive
has_one_attached :zip
validates :name, presence: true
validate :zip_should_be_presence
# https://github.com/rails/rails/issues/31656
def zip_should_be_presence
if zip.attached?
if !blob_is_zip?
zip.purge # ActiveStorage::Blob.unattachedでお掃除バッチを作ることを考えるとここでpurgeしなくてもいいかも。
errors.add(:zip, 'はZIPではありません')
end
else
errors.add(:zip, :presence)
end
end
def blob_is_zip?
zip.blob.content_type == 'application/zip' && zip.blob.filename.extension_without_delimiter == 'zip'
end
end
添付ファイルでバリデーションエラー
ファイル名をhoge.jpg
にしている。今回のモデルの定義ではpurge
を実行するようにしているので削除される。
irb(main):007:0> Archive.create!(name: 'hoge', zip: {io: File.open('hoge.zip'), filename: 'hoge.jpg'})
Disk Storage (4.1ms) Uploaded file to key: gvRhRYR6kYopMacbhdbATQQH (checksum: mTlNhQT67kf1chY3Gdtydg==)
(0.1ms) begin transaction
ActiveStorage::Blob Create (1.4ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["key", "gvRhRYR6kYopMacbhdbATQQH"], ["filename", "hoge.jpg"], ["content_type", "application/zip"], ["metadata", "{\"identified\":true}"], ["byte_size", 326], ["checksum", "mTlNhQT67kf1chY3Gdtydg=="], ["created_at", "2018-04-19 05:19:41.046491"]]
(1.6ms) commit transaction
(0.0ms) begin transaction
(0.1ms) commit transaction
(0.0ms) begin transaction
Disk Storage (0.2ms) Deleted file from key: gvRhRYR6kYopMacbhdbATQQH
ActiveStorage::Blob Destroy (0.6ms) DELETE FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = ? [["id", 48]]
(0.6ms) rollback transaction
Traceback (most recent call last):
1: from (irb):7
ActiveRecord::RecordInvalid (バリデーションに失敗しました。 ZipはZIPではありません)
Archive
モデル側でバリデーションエラー
blobは問題ないので特に削除されない。
irb(main):003:0> Archive.create!(zip: {io: File.open('hoge.zip'), filename: 'hoge.zip')
Disk Storage (4.5ms) Uploaded file to key: rYvGGj9FDYDvgcrCyqn3oVUs (checksum: mTlNhQT67kf1chY3Gdtydg==)
(0.1ms) begin transaction
ActiveStorage::Blob Create (1.5ms) INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["key", "rYvGGj9FDYDvgcr
Cyqn3oVUs"], ["filename", "hoge.zip"], ["content_type", "application/zip"], ["metadata", "{\"identified\":true}"], ["byte_size", 326], ["checksum", "mTlNhQT67kf1chY3Gdtydg=="], ["created_at", "2018-04-19 05:18:43.65
2190"]]
(1.3ms) commit transaction
(0.1ms) begin transaction
(0.1ms) commit transaction
(0.0ms) begin transaction
(0.1ms) rollback transaction
Traceback (most recent call last):
1: from (irb):3
ActiveRecord::RecordInvalid (バリデーションに失敗しました。 Nameを入力してください。)
迷子のblob
unattached
というお掃除バッチ用のスコープがある。
# https://github.com/rails/rails/pull/31970
ActiveStorage::Blob.unattached.find_each(&:purge_later)
ダイレクトアップロード(先にActiveStorage::Blob
を作っておいて、ActiveStorage::Blob#signed_id
を使って紐付けを行う仕組み)などを使うとこういうBlobがたくさん作られるので、お掃除バッチの作成は必須ですね。