- Active Strorage 概要
- Active Storage の環境構築
- Active Storage のセットアップ
- パラメータに許可を与える
- ファイルをレコードに添付する
- ビューを設定する
- variant で画像を変形する
- 参考
Active Strorage 概要
Active Storageはクラウドストレージサービス(Amazon S3, Google Cloud Storage等)へのファイルアップロードや、ファイルを Active Record オブジェクトにアタッチする機能を提供する。
その他にも、アプリケーションにアップロードした画像の変形や、PDFや動画等の画像以外のアップロードファイルの内容を画像にしたり、任意のファイルからメタデータ抽出にも利用できる。
Active Storage の環境構築
Active Storage の多くの機能は、サードパーティソフトウェアに依存しているため、別途インストールする。インストール対象を下記にまとめる。
ライブラリ名 | 概要 | 備考 |
---|---|---|
libvips | 画像解析や画像変形用 | v8.6以降 |
FFmpeg | 動画や音声の解析や動画プレビュー用 | v3.4以降 |
Poppler | PDFプレビュー用 | - |
それぞれインストールしていく。
次に画像分析、画像加工のために image_processing
gem も必要ので Gemfile のコメントを外すか、下記を追加する。
gem "image_processing", ">= 1.2"
Active Storage のセットアップ
Active Storage では3つのテーブルを使用する。
- active_storage_blobs
- active_storage_variant_records
- active_storage_attachments
上記を作るために、下記コマンドを実行する。
% rails active_storage:install
上記コマンドを実行すると、xxx_create_active_storage_tables.active_storage.rb
というマイグレーションファイルが作られる。
マイグレーションファイルを実行して、モデルを作るために下記を実行する。
% rails db:migrate
Active Storage のサービスを config/storage.yml で宣言する。サービスを Active Storage を認識させるために、Rails.application.config.active_storage.service
を設定する。
上記の設定は、環境ごとに行うことが推奨されているので、 development 環境で使うために、 config/environments/development.rb
に下記を追加する。
# ファイルをローカルに保存する config.active_storage.service = :local
パラメータに許可を与える
まずは、deviseで画像データを扱えるように、アプリケーションコントローラで許可を与える。
復習として、Strong Parameters により、モデルのデータ更新には、許可する属性をコントローラで明示的に指定する必要がある。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base ... before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters keys = %i[name postal_code address self_introduction avatar] devise_parameter_sanitizer.permit(:sign_up, keys: keys) devise_parameter_sanitizer.permit(:account_update, keys: keys) end ... end
ファイルをレコードに添付する
User モデルに画像を添付するために、User モデルを以下のように定義する。
# app/models/user.rb class User < ApplicationRecord ... has_one_attached :avatar ... end
ビューを設定する
画像をアップロードする form
メソッドを持つビューには、 <%= form.file_field :avatar %>
を追加する。
<!-- app/views/devise/registrations/new.html.erb, edit.html.erb --> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> ... <div class="field"> <%= f.label :avatar %><br /> <%= f.file_field :avatar %> </div> ...
画像を表示するビューには、 <%= image_tag user.avatar if user.avatar.attached? %>
を追加する。
<!-- app/views/users/index.html.erb, show.html.erb --> ... <%= image_tag(user.avatar) if user.avatar.attached? %> ...
avatar.attached?
メソッドにて、特定のuserがアバター画像を持っているかどうかを調べて、持っていれば image_tag
メソッドに画像を渡す。
上記の条件文がない場合、下記のようなエラーとなる。
Can't resolve image into URL: undefined method `persisted?' for nil:NilClass
パッと調べた感じでは、image_tag
メソッドに nil
オブジェクト(画像データを持っていないレコード)を渡すとエラーになってしまう。
ここまでしてあげると、下記のように画像を上げられて、一覧画面にも表示されるようになる😄
variant で画像を変形する
画像の変形には、variant
メソッドを用いる。ビューにて下記を実施する。
- <%= image_tag(user.avatar) if user.avatar.attached? %> + <%= image_tag user.avatar.variant(resize_to_limit: [100, 100]) if user.avatar.attached? %>
上のコードでは、高さと幅を 100px ✖️ 100px に制限したavatar
BLOB のバリアントを作成し、処理する。