FBCのRailsプラクティスも残り僅かになってきました。 Active Storageを使って画像アップロード機能を実装するという新しい課題に着手しました。 Acrive Storageを使った画像アップロード機能のセットアップについて調べました。
今回は次のような条件での実装を想定してセットアップします。
- 既存のuserモデルにアイコンを表示する
- 1つのレコードに対して1枚の画像
- 画像の保存先はローカル
以下が実装するアプリのリポジトリです。
karlley/fjord-books_app at my-user_icon
結論
下記手順でセットアップを行う。
- gemの準備
- Active Storage セットアップ
- 画像ファイル保存先の設定
- 画像を表示させるモデルへの追記
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セットアップ用コマンドを実行することで上記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
に記述します。
今回はデフォルトの設定のままローカルに保存する設定で進めます。
-- 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_attached
とhas_many_attached
を使い分ける必要があります。
- 1枚の画像ファイル:
has_one_attached :属性名単数形
- 複数の画像ファイル:
has_many_attached :属性名複数形
Active Storageを使った画像アップロード機能のセットアップは以上です。
あとは次の作業を行えば画像アップロードと画像の表示ができるはずです。
- contollerファイルに追加したavatar属性をパラメータに追加
- viewファイルでの画像表示部の追加
ここの部分は環境によってかなり変わるので今回は割愛します。
まとめ
Active Storageのセットアップだけで結構時間掛かってしまった。 それにしてもこれだけの設定で画像アップロードを実装できてしまうなんてRailsはやっぱり凄い。