Active Storage移行記:バリデーション編|sitateru tech blog

シタテルの技術やエンジニアの取り組みを紹介するテックブログです。

2018年11月26日月曜日

Active Storage移行記:バリデーション編

こんにちはあさのです。

今回は、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からの移行はいろいろと作業があったので他のトピックについてもまた書いていきたいと思います。

それでは。

, , , ,