Active Storageを使った画像アップロード機能のセットアップ

FBCRailsラクティスも残り僅かになってきました。 Active Storageを使って画像アップロード機能を実装するという新しい課題に着手しました。 Acrive Storageを使った画像アップロード機能のセットアップについて調べました。

今回は次のような条件での実装を想定してセットアップします。

  • 既存のuserモデルにアイコンを表示する
  • 1つのレコードに対して1枚の画像
  • 画像の保存先はローカル

以下が実装するアプリのリポジトリです。

karlley/fjord-books_app at my-user_icon

結論

下記手順でセットアップを行う。

  1. gemの準備
  2. Active Storage セットアップ
  3. 画像ファイル保存先の設定
  4. 画像を表示させるモデルへの追記

1. 必要なツールの準備

必要なgem等のツールについてはこちらの記事にまとめました。 今回使用するツールは次の4つです。

  • Active Storage
  • Image Magick
  • MiniMagick
  • image_processing

この4つの中でImage Magickとimage_processingはインストールされていないので個別に準備します。

  • Image Magick: brew install imagemagick でインストール
  • image_processing: Gemfileコメントアウトを外しbundle install

2. Active Storage セットアップ

Active Storageを使う為には次の3つのテーブルが必要です。

  • active_storage_blobs
  • active_storage_variant_records
  • active_storage_attachments

Active Storage の概要 - Railsガイド

次のActive Storageセットアップ用コマンドを実行することで上記3つのテーブルを作成するマイグレーションファイルが作成されます。

$ rails active_storage:install
Copied migration 20221004202735_create_active_storage_tables.active_storage.rb from active_storage

作成されたマイグレーションファイル

# db/migrate/xxx_create_active_storage_table.active_strage.rb

# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
  def change
    create_table :active_storage_blobs do |t|
      t.string   :key,          null: false
      t.string   :filename,     null: false
      t.string   :content_type
      t.text     :metadata
      t.string   :service_name, null: false
      t.bigint   :byte_size,    null: false
      t.string   :checksum,     null: false
      t.datetime :created_at,   null: false

      t.index [ :key ], unique: true
    end

    create_table :active_storage_attachments do |t|
      t.string     :name,     null: false
      t.references :record,   null: false, polymorphic: true, index: false
      t.references :blob,     null: false

      t.datetime :created_at, null: false

      t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
      t.foreign_key :active_storage_blobs, column: :blob_id
    end

    create_table :active_storage_variant_records do |t|
      t.belongs_to :blob, null: false, index: false
      t.string :variation_digest, null: false

      t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true
      t.foreign_key :active_storage_blobs, column: :blob_id
    end
  end
end

作成したマイグレーションファイルを反映させます。

$ rails db:migrate

3. 画像ファイル保存先の設定

アップロードした画像の保存先の設定はconfig/storage.yml に記述します。

Active Storage の概要 - Railsガイド

今回はデフォルトの設定のままローカルに保存する設定で進めます。

-- config/storage.yml

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
...

development環境用で設定を読み込む必要があるのでconfig/environments/development.rb に次の記述があるか確認します。

# config/environments/development.rb

...
  # Store uploaded files on the local file system (see config/storage.yml for options).
  config.active_storage.service = :local
...

環境別に保存先の設定を変えたい場合は次のようにファイルを作成して追加設定します。

  • 本番環境: config/environments/production.rb
  • テスト環境: config/environments/test.rb

4. 画像を表示させるモデルへ属性の追加

今回は既存のuserモデルに画像1枚を表示したいのでapp/models/user.rb に以下を追記します。 画像を表示用の属性として:avatar を設定します。ここの属性名は任意に決めて大丈夫です。

# app/models/user.rb

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  # 下記を追記
  has_one_attached :avatar
end

has_one_attached とhas_many_attached について

レコードに添付する画像ファイルの数に応じてhas_one_attachedhas_many_attached を使い分ける必要があります。

  • 1枚の画像ファイル: has_one_attached :属性名単数形
  • 複数の画像ファイル: has_many_attached :属性名複数形

Active Storage の概要 - Railsガイド

Active Storageを使った画像アップロード機能のセットアップは以上です。

あとは次の作業を行えば画像アップロードと画像の表示ができるはずです。

  • contollerファイルに追加したavatar属性をパラメータに追加
  • viewファイルでの画像表示部の追加

ここの部分は環境によってかなり変わるので今回は割愛します。

まとめ

Active Storageのセットアップだけで結構時間掛かってしまった。 それにしてもこれだけの設定で画像アップロードを実装できてしまうなんてRailsはやっぱり凄い。

参照

Active Storage の概要 - Railsガイド

ActiveStorageを使ってお手軽にファイルアップロードを試す - Qiita