はじめに
Ruby on Railsには、クラウドストレージサービスへのファイルのアップロードを行う機能を提供するActive Storageがあります。
Rails5.2から登場したActive Storageですが、当初はできることが少なく、CarrierWaveを利用する方も多かったのではないでしょうか。
Rails7まででActive Storageには様々な機能が追加され、新規開発の際はActive Storageを選択することが多くなると思います。
今回はActive Storageの導入からよく使うであろう画像のリサイズの方法までをご紹介します。
ViewやControllerまわりについては説明していないのでRailsガイドなどで確認してください。
開発環境
こちらの記事を参考にRails7 + MySQLの開発環境ができている前提で話を進めていきます。
libvipsのインストール
Active Storageで取り扱いたいファイルの種類に応じて、必要なライブラリをインストールする必要があります。今回は画像を取り扱いため、libvipsをインストールします。(ImageMagickでも良いですがlibvipsの方が処理が高速なためそちらを選択)
Dockerfileにlibvipsインストールの記述を追加します。(RUN bundle install
の前)
RUN apt-get update && apt-get install -y libvips42
image_processing gemのインストール
image_processing gemも必要なため、Gemfileのコメントアウトを外します。
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
gem "image_processing", "~> 1.2"
この段階でbuildしておきます。
docker-compose build
ActiveStorage用のmigrateファイルの作成
ActiveStoregeでは3つのDBテーブルが必要となります。
-
active_storage_blobs
: ファイルの実体(blob)を保存しておくテーブル -
active_storage_attachments
: ActiveRecordと↑のファイルの実体(もとの画像)を紐づけるテーブル -
active_storage_variant_records
: ActiveRecordと↑のファイルの実体(後述するvariantで作成された画像)を紐づけるテーブル
テーブルを作成するためのmigrateファイルは下記コマンドで作成することができます。
docker-compose run --rm web rails active_storage:install
利用するサービス(保存先)を設定する
ファイルの保存先はローカルやS3などいろいろ設定することができます。今回は開発環境でローカル利用するために必要な設定を行います。
サービスの定義をconfig/storage.yml
に記述します。
ローカルはすでに定義されているため変更不要です。
local:
service: Disk
root: <%= Rails.root.join("storage") %>
利用するサービスをActiveStorageに認識させるためにconfig/environments/development.rb
に下記を追加します。
config.active_storage.service = :local
ファイルをレコードに紐づける
Userモデルを作成します。アバター画像を紐づけたいので以下のジェネレーターコマンドを実行します。
docker-compose run --rm web rails generate model User name:string avatar:attachment
実行後に以下のようなモデルが作成されます。
class User < ApplicationRecord
has_one_attached :avatar
end
has_one_attached
でレコードとファイルの間に1対1の紐づけができます。
variantを使って画像をリサイズする
variantを利用することで、もとの画像ファイルはそのままに、サイズ違いの画像を作成することができます。
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
end
上記ではthumb
というvariant名で、最大で幅100px高さ100pxの画像となるようにリサイズされた画像を利用できるようになります。その他の画像処理の指定方法などはimage_processingのREADMEを確認してください。
variantはuser.avatar.variant(:thumb)
のような形で呼び出すことができます。
初回の呼び出し時に画像を作成・保存し、次回以降は保存されたリサイズ済みの画像を取得するようになります。