こんにちはあさのです。
今回は、Ruby on Railsのファイルアップロード機能をPaperclipからActive Storageに移行したときの話を書こうと思います。
Paperclip
Paperclipはファイルアップロード用のGemです。
https://github.com/thoughtbot/paperclip
比較的導入が簡単であり、アプリケーションにファイルアップロード機能をつけるためによく使われています。
ですが、現在は "Deprecated" とされていて、Rails 5.2から標準機能の1つとなったActive Storageへの移行が推奨されています。
Active Storage
Active StorageはRailsのバージョン5.2から標準搭載されている機能の一つで、Paperclipと同様Active Recordのオブジェクトと紐づけたファイルアップロード機能を提供しています。
https://github.com/rails/rails/tree/master/activestorage
シタテルでもRails 5.2へのアップグレードが落ち着いたところでこの移行を行いました。
そんなわけで、移行にあたっていくつか注意点となったところを振り返っていきたいと思います。
今回はモデルのバリデーションの話です。
Active Storage でのバリデーション
Papaerclipにはバリデーション機能があります。
以下はiconという名前で扱う添付ファイルのバリデートをする例で、モデル内にこう書いておけば保存時に自動でチェックされます。
見てのとおりですが、ファイル形式は[jpg, jpeg, gif, png]のどれか、ファイルサイズが10MB以下である必要があります。
validates_attachment :icon,
content_type: {
content_type: [
'image/jpg',
'image/jpeg',
'image/gif',
'image/png'
]
},
size: {
less_than_or_equal_to: 10.megabytes,
message: I18n.t('errors.messages.file_too_large')
}
しかしActive Storageにはこのようなバリデーション機能はありません。
じゃあどうするんだ!という話ですが、素直にActive Recordのカスタムバリデーションを使いましょう。
これで同じようなことができます。
validate :validate_icon
def validate_icon
return unless icon.attached?
if icon.blob.byte_size > 10.megabytes
icon.purge
errors.add(:icon, I18n.t('errors.messages.file_too_large')
elsif !image?
icon.purge
errors.add(:icon, I18n.t('errors.messages.file_type_not_image'))
end
end
def image?
%w[image/jpg image/jpeg image/gif image/png].include?(icon.blob.content_type)
end
ちなみに、
attached?
はファイルが存在するかどうかblob.byte_size
はファイルサイズblob.content_type
はファイルタイプ
を取得しています。
ということでActive Storageのバリデーションについて書いてみました。
Paperclipからの移行はいろいろと作業があったので他のトピックについてもまた書いていきたいと思います。
それでは。