Active Storageを技術検証して導入しないことにした理由

みんなのウェディングのエンジニア合原です。 今回はRails5.2より導入されているActive Storageを使って、画像アップロードを実現できないか、さらに、 弊社のスタンダードな画像アップロード方法として、導入できないか技術検証してみた話をします。

Active Storageとは

Active Storageとは、 下記の通り、Rails5.2より追加されたファイルアップロードを行うための機能です。これを使うと、投稿フォーム等で容易にファイルアップロードが実現できます。

Active StorageとはAmazon S3、Google Cloud Storage、Microsoft Azure Storageのような クラウドストレージサービスへのファイルのアップロードとそれらのファイルをActive Recordオブジェクトに添付することを容易にします。 開発およびテスト用のローカルディスクベースのサービスが付属しており、ファイルをバックアップおよび移行用の従属サービスにミラーリングすることができます。

Active Storageのテーブル設計

下図に示す通り、ポリモーフィック関連のテーブル設計を前提としています。 blobsテーブルが画像のメタ情報やファイルパスなど、画像自体のデータを保持し、attachementsテーブルがblobsと該当モデルとの紐付けの役割を担います。 詳しくは、Active Storageをご覧ください。

イメージ図(S3へのアップロードを想定)

※便宜上テーブルカラム等は簡略化しています。

なぜActive Storageなのか

弊社の画像アップロードの課題

  • 統一された画像アップロードの仕組みがない
  • 決して良いとは言い難いレガシーなデータモデリング(設計)への依存が強く、実装時のコスト高
  • サーバーを経由した画像アップロードのため大きい画像ファイルの場合アプリ側でのケアが必要

どう使おうとしたのか

単に画像(ファイル)アップロードを実現するだけなら、Active Storage標準の機能のみで問題はありません。 しかし、弊社で取り扱う画像にはユーザーからの投稿画像があり、審査を行う必要があります。つまり、審査ステータスもテーブル管理する必要があります。 このことを踏まえ以下のステップでActive Storageを利用することを前提に技術検証をしてみました。

  1. 実際の利用を想定して新しいテーブル設計をしてみる
  2. S3へのアップロードを試してみる

テーブル設計

そこで下記のようなテーブル設計をしてみました。 Active Storage標準のテーブル構成に関連する形で、画像自体の審査ステータスも管理できるデータモデリングをしてみました。 とりあえず、新たなテーブル構成でActive Storageを利用できる状態を実現できました。 (※実際はもう少し複雑なテーブル構成となりました)

S3へのアップロード

前述の通り、Active Storageでは標準でymlを使って、S3のバケットをアップロード先として指定できます。

amazon:
  service: S3
  access_key_id: <%= ACCESS_KEY %>
  secret_access_key: <%= SECRET_ACCESS_KEY %>
  region: "ap-northeast-1"
  bucket: "images"

実はこの機能、バケット単位でしか指定ができません。(=オブジェクトキーの指定ができません。) 言い換えると、Active Storageを利用してアップロードされた、あらゆるファイルが一つのバケットに混在する状態となってしまいます。

弊社の各種サービスでも利用することを想定した場合、この状態は受け入れられません。 例えば、ネットワーク障害やアプリケーション側でのバグによりアップロードが正常に出来なかった場合、つまり、上述のテーブルと画像の実態ファイルとの同期が取れなくなった場合、画像の識別ができなくなってしまうことが想定されます。

まとめ

Active Storageを使うべきか

ここまでの点をまとめると、

  • 複雑な要件になるとテーブル設計がActive Storageを使うために複雑になってしまう
  • 画像のアップロード先が柔軟に設定できない

上記が懸念点として考えられ、今回はActive Storageの導入を見送ることとしました。今後Active Storageを使うことを考える機会がありましたら、 ぜひこちらの記事も参考にしてみてください。 また、弊社では上述の課題については、別のやり方で現在対応中です。折を見て、こちらで発信していきます!