32
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rails]Active Storageを理解してない人は覗いてご覧なさい

Last updated at Posted at 2021-07-11

はじめに

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用の宣言をする。

app/models/user.rb
class User < ApplicationRecord
  # 1対1(単数枚画像投稿)で関連付けるという宣言
  has_one_attached :portrailt

  # 1対多(複数枚画像投稿)で関連付けるという宣言
  has_many_attached :portrailts
end

仕組みとDB構成

Active Storageは、アプリケーションのデータベースでactive_storage_blobsactive_storage_attachmentsという名前の2つのテーブルを使用します。
テーブル間のリレーション(関係性)は以下の図の通りです。

スクリーンショット 2021-07-11 22.28.16.png

参考:【Rails6.0】Active Storageを用いた単数枚、複数枚画像投稿の実装手順をそれぞれ解説

  • active_storage_blobsテーブル
    • アップロードファイルのメタ情報を管理するモデル。
  • active_storage_attachments
    • 主となるモデルとactive_storage_blobsテーブルの中間テーブル。

ファイル保存場所の設定

デフォルトでは、ローカルのファイルシステムに保存しています。しかし、本番環境ではS3などクラウドストレージを利用することが多いため。設定ファイルを用意する。

config/storage.yml
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.ビューでサムネイルを表示させる。

app/views/users/show.html.erb
...
  # portrailt.variantメソッドに渡したメソッドは、ImageProcessingメソッドとして実行される
  <%= image_tag @user.portrailt.variant(resize_to_limit: [100, 100]) %>
...

ダイレクトアップロード機能

1.下記のJavaScriptライブラリを読み込む。(Rails6系はデフォルトで読み込み済)

app/javascript/packs/application.js
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/)

32
26
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?