PaperclipからActive Storageに移行した

Rails 5.2でActive Storageが使えるようになった。プライベートで作っているRailsアプリケーションをPaperclipからActive Storageに移行してみたのでその記録です。

Active Storageの概要

Railsガイドを読みましょう

Active Storage の概要 | Rails ガイド

  • active_storage_blobsというテーブルで画像の情報を保存する
  • 画像本体はS3などに保存
  • active_storage_attachmentsというテーブルで画像とモデルクラスを対応づける
  • この2つのテーブルを扱うモデルクラスもついてくる

移行手順

PaperclipのGithubリポジトリに以下の文書があるので、だいたいこの通りにやればよい。

paperclip/MIGRATING.md at master · thoughtbot/paperclip

ざっと読んで、以下の手順でやった。 フェーズごとにデプロイする。

  • 第一フェーズ
  • 第二フェーズ
    • rails activestorage:installを実行してテーブルを作成
    • Active Storage用のテーブルにレコードを作成する(rakeタスク)
    • 画像ファイルをActive Storageが参照する位置にコピー(rakeタスク)
  • 第三フェーズ
    • モデルクラスを修正してPaperclipからActive Storageを使うようにする
  • 第四フェーズ
    • 後片付け
      • Paperclip用のカラムを削除
      • Paperclipが参照していた画像ファイルを削除

利用者がほぼいないサービスなのでシュッとやったが、ちゃんとやるなら第二フェーズと第三フェーズの間に画像が追加、変更、削除される可能性があるので、その辺を考える必要がある。

ハマったこと

ローカルとS3の画像パスの違い

Active Storageは画像をローカルディスクに保存する場合、画像のキー文字列(active_storage_blobs.key)の先頭4文字を使ってディレクトリを切っている。例えばキーが6MdeAsGrsszAvRPMykYu1dC2なら6M/de/6MdeAsGrsszAvRPMykYu1dC2というパスに保存する。一方、S3に保存する場合はこのようなことをせず、キー名を直接使う。

画像ファイルをコピーするときはこのことに気をつける必要がある。ディレクトリを切る方式でS3にコピーするといざActive Storageに切り替えたとき画像が参照できない。

移行に使ったrakeタスク

DBはポスグレでCafeというクラスが1つの画像を持っているという前提です。

https://gist.github.com/takatoshiono/a6c5548f17ff487e88891d8307410760

まとめ

プライベートで作っているRailsアプリケーションでActive Storageを使ってみました。Paperclipからの移行手順が公開されていたので便利でしたが、少しだけハマりました。

これが標準でついてくるRails 5.2、便利ですね。