はじめに
Rails5.2から、公式でファイルアップロード機能が提供されました。それがActive Storage
です。アプリケーションでActive Storageを用いることで、ImageMagickで画像のアップロードを変換したり、 PDFやビデオなどの非画像アップロードの画像表現を生成したり、任意のファイルからメタデータを抽出したりできます。
使用方法
1.Active Storageに必要なファイルを生成する。
$ rails active_storage:install
2.ファイルアップロードを利用したいモデルを生成する。
※今回はscaffoldを利用してUser関連のファイルを生成しています。
# portraitというActive Storage用属性を追加する
$ rails g scaffold user name portrait:attachment
rails db:migrate
で、マイグレーションファイルを実行する。
3.主となるモデルにActiveStorage用の宣言をする。
class User < ApplicationRecord
# 1対1(単数枚画像投稿)で関連付けるという宣言
has_one_attached :portrailt
# 1対多(複数枚画像投稿)で関連付けるという宣言
has_many_attached :portrailts
end
仕組みとDB構成
Active Storageは、アプリケーションのデータベースでactive_storage_blobs
とactive_storage_attachments
という名前の2つのテーブルを使用します。
テーブル間のリレーション(関係性)は以下の図の通りです。
参考:【Rails6.0】Active Storageを用いた単数枚、複数枚画像投稿の実装手順をそれぞれ解説
- active_storage_blobsテーブル
- アップロードファイルのメタ情報を管理するモデル。
- active_storage_attachments
- 主となるモデルとactive_storage_blobsテーブルの中間テーブル。
ファイル保存場所の設定
デフォルトでは、ローカルのファイルシステムに保存しています。しかし、本番環境ではS3などクラウドストレージを利用することが多いため。設定ファイルを用意する。
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket
...
Tips
サムネイルの作成
1.Gemfileに以下を記載し、bundle install
を実行する。
gem 'image_processing'
2.以下のコマンドを実行し、ImageMagickをインストールする。
$ brew install imagemagick
3.ビューでサムネイルを表示させる。
...
# portrailt.variantメソッドに渡したメソッドは、ImageProcessingメソッドとして実行される
<%= image_tag @user.portrailt.variant(resize_to_limit: [100, 100]) %>
...
ダイレクトアップロード機能
1.下記のJavaScriptライブラリを読み込む。(Rails6系はデフォルトで読み込み済)
require('@rails/activestorage').start()
// こちらの場合もあります
ActiveStorage.start()
2.file_fielsにオプションを追加する。
※direct_upload: true
で、ダイレクトアップロード機能を有効にし、複数のファイルを同時アップロードしたい場合はmultiple: true
とする。
...
<%= form.file_field :portrait, direct_upload: true, multiple: true %>
...
注意点
少し改善点はあるものの、今後の利用者が増えることに従い、これらの課題は解決されていくと思います。
既存のgemなどを利用している場合は移行した方が良い?
無理にActiveStorageに移行する必要は、利用しているライブラリのメンテナンスが終了していて、ActiveStorageへの移行を推奨している場合を除き、コストの観点から必須ではないです。
Validationヘルパーの不足
ActiveStorageには、バリデーション用のヘルパーメソッドが無いので自力で実装
もしくはActiveStorageValidations等のgem
利用しなければいけないです。
cacheの不足
バリデーションエラー時には、現在はキャッシュ機能がないので画像をもう一度アップロードしないといけないです。
終わりに
今まではCarrierWaveなどを使って画像アップローダーを作成していたので、標準装備で実装できるのはいいですよね!今後は、こっちがスタンダードになってくると思うので、今のうちに扱いを覚えておこう。。
参考
[Active Storage の概要]
(https://railsguides.jp/active_storage_overview.html)
[rails/activestorage]
(https://github.com/rails/rails/tree/main/activestorage)
[image_processing/doc/minimagick.md]
(https://github.com/janko/image_processing/blob/master/doc/minimagick.md)
[ImageMagick]
(https://imagemagick.org/script/)