はじめに
現在未経験から転職活動のポートフォリオを作成しております。Active Storageについてわからなかったところを重点的に備忘録として作成しました。
Active Storageとは
Active Storageは、Amazon S3、Google Cloud Storage、Microsoft Azure Storageなどのクラウドストレージサービスへのファイルのアップロードや、ファイルをActive Recordオブジェクトにアタッチする機能を提供します。 development環境とtest環境向けのローカルディスクベースのサービスを利用できるようになっており、ファイルを下位のサービスにミラーリングしてバックアップや移行に用いることも可能です。
Active Storageは、アプリケーションにアップロードした画像の変形や、PDFや動画などの画像以外のアップロードファイルの内容を代表する画像の生成、任意のファイルからのメタデータ抽出にも利用できます
まとめるとこんな感じ
Active Storageの重要ポイント
📦 ファイル保存先
クラウドストレージに対応: Amazon S3、Google Cloud Storage、Azure Storage
ローカルディスクも使える: development環境とtest環境向け
🔗 基本機能
ファイルアップロード: クラウドやローカルにファイルを保存
Active Recordにアタッチ: モデル(User、Postなど)にファイルを紐付け
🎨 画像処理
画像の変形: リサイズ、トリミングなど
サムネイル生成: PDFや動画から代表画像を作成
🛠️ その他の機能
ミラーリング: ファイルを複数のストレージにバックアップ
メタデータ抽出: ファイルサイズ、形式、寸法などの情報を取得
Active Storageの導入方法
以下の流れで行う
1 DBにテーブル作成
2 ファイルの保存先のストレージ設定
3 ファイルをモデル(レコード)に添付する
1 DBにテーブル作成
まずはActiveStorageに必要なマイグレーションを生成する。
rails active_storage:install
これによってActiveStorageが使用する3つのテーブルを作成するマイグレーションが生成される。(各テーブルの用途は後ほど説明します)
・active_storage_blobs
・active_storage_variant_records
・active_storage_attachments
次に、マイグレーションを実行してDBに反映(先ほどの3つのテーブルを作成)
rails db:migrate
以下の3つのテーブルが生成される。
== 20210811020333 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs, {})
-> 0.1982s
-- create_table(:active_storage_attachments, {})
-> 0.0799s
-- create_table(:active_storage_variant_records, {})
-> 0.0805s
== 20210811020333 CreateActiveStorageTables: migrated (0.3589s) ===============
2 ファイルの保存先のストレージ設定
Active Storageのサービスはconfig/storage.ymlで宣言する。
「アプリケーションが使うサービス」 ごとに、名前と必要な構成を指定する。
例えば以下の場合では、local、test、amazonという3つのサービスを宣言している。
# config/storage.yml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
amazon:
service: S3
access_key_id: ""
secret_access_key: ""
bucket: ""
region: "" # 例: 'ap-northeast-1'
次に、先ほど設定した利用サービスをActive Storageに認識させるため、Rails.application.config.active_storage.serviceを設定していく必要がある。
使うサービスは環境ごと (開発・テスト・本番) に異なることもあるため、この設定を環境ごとに行うのが良いらしい。
・development環境 でローカルDiskサービスを使うには、
config/environments/development.rbに以下を追加
# ファイルをローカルのディスクに保存する
config.active_storage.service = :local
・test環境 でtestサービスを利用するには、config/environments/test.rbに以下を追加
# ローカルファイルシステム上のアップロード済みファイルを一時ディレクトリに保存する
config.active_storage.service = :test
・production環境 でAmazon S3を利用するには、config/environments/production.rbに以下を追加
# ファイルをAmazon S3に保存する
config.active_storage.service = :amazon
3 ファイルをモデル(レコード)に添付する
ActiveStorageを使って画像などのデータを既存のテーブルと紐づけるために、モデルファイルに紐付け関連を追加する
「1つのファイルを追加する場合」と 「複数のファイルを追加する場合」で実装方法が異なるが、今回はプロフィール画像として実装するので「1つのファイルを追加する場合」にフォーカスして解説する
User モデルを開いて、以下を追加してください
class User < ApplicationRecord
has_one_attached :image # ← この1行を追加
end
- has_one_attached は Active Storage で画像1枚を関連付けるメソッド
- これで user.image でファイルにアクセスできます
使用したメソッドmemo
image属性をそのままフロント側に返そうとすると、Active Storageの複雑なオブジェクトがJSONにシリアライズできず、無限ループが発生しました。この問題を解決するため、imageオブジェクトをURL文字列に変換する必要があり、以下のメソッドを使用しました。他にも多くのメソッドがありますが、気になる方はrailsガイドを参照してください!
user.image.attached?
- 画像が添付されているか確認するメソッド
rails_blob_path(user.image, disposition: "inline")
- URLを生成するメソッド
- user.avatar : 生成される対象の画像を指定
- disposition: "inline" : HTTPヘッダーのContent-Dispositionの値を指定する
disposition について
- "inline" - ブラウザで表示(プロフィール画像に適している)
- "attachment" - ダウンロード(ファイルとして保存させたい場合)
プロフィール画像の場合は "inline" が適切です。
参考
Claude Sonnet4.5