はじめに
普段web開発を行う際、画像アップロードの要件がある場合、
RailsのActiveStorageを使っています。
ActiveStorageの基本的な使い方については以下ドキュメントをご確認ください。
今回、複数枚アップロードする時に罠があったため、記しておこうと思います。
罠の内容
結論から言うと、attach処理をtransaction内で行うと、指定のStorage(S3とかDisk)には一枚しかファイルがアップロードされず、成功した一枚以外のファイルのURLを参照すると404となってしまいます。
ドキュメント通りmodelにattachの設定をする
has_many_base64_attached :images
modelと、添付される画像の保存処理失敗時の整合性を取りたいので、transactionを書く
ActiveRecord::Base.transaction do
model.build_hogehoge(params)
model.save!
params[:images].each do |image|
model.images.attach(image) #attachはimagesの保存もなされるためsaveは記載しない
end
end
実際にローカルで3枚画像アップロード処理を実行してみると、
以下のDisk Storage....のログが最後の1枚に対してしか出ませんでした。え?
active_storage_blobs、active_storage_attachments、active_storage_variant_recordsレコード自体は作成されています。
しかし、rails_blob_pathや、rails_storage_proxy_pathで得られるURLから画像参照すると、
1枚目と2枚目の画像は404となっていました。
対応状況
issueが上がっていました。
対応方法
該当のattachの処理部だけをtransactionから外す。という形で対応しました。
挙動としては問題なく動いています。
が、
今回の記事作成に伴い、もう少し深く調べてみました。
すると...
修正されてマージされてるやん。
rails7.1からちゃんと動くみたいやん。
なんで当時ちゃんと見なかったんだろうか...
最後に
最近他でもバージョンが古いことによるバグに遭遇したんですよね。。
自分が普段使う技術をもっと知る必要があると感じたのと、
定期的に最新のバージョンに上げることの重要性を改めて感じました。
バージョンを上げる事を怖がってはいけませんね。
そのためにしっかりテストを書かないとなぁ。