【Rails】Active Storageについて徹底解説!

Rails

Active Storageとは

Active Storageはファイルアップロードを簡単に実装できるgemです。

railsの標準のgemファイル
リンクをコピーしました

Active Storageというgemを使うと簡単にファイルをアップロードする機能を実装することができます。
これはrailsの標準のgemで、rails5.2から追加されました。

使い方
リンクをコピーしました

Active Storageを使うには以下のコマンドを実行します。

shell
1
2
$ rails active_storage:install
$ rails db:migrate

最初のコマンドを実行するとactive_storage_blobsactive_storage_attachmentsという2つのテーブルを作成するマイグレーションファイルが生成されます。
active_storage_blobsは実際にアップロードしたファイルが保存されるテーブルで、active_storage_attachmentsは中間テーブルになります。

次にモデルに対してActive Storage用の設定を追加します。

1つのファイルを追加する
リンクをコピーしました

ruby
1
has_one_attached :カラム名

上のように記述すると1つのファイルを選択します。

複数のファイルを追加する
リンクをコピーしました

複数のファイルをアップロードしたい場合は下記のように記述します。

ruby
1
has_many_attached :カラム名

保存するカラム名の命名方
リンクをコピーしました

usersモデルに「image」というカラムで保存したい場合はmodelフォルダ内のusers.rbにこのように記述します。

ruby
1
has_one_attached :image

ここでのポイントはわざわざusersテーブルにカラムを追加する必要がないということです。
これは非常に便利ですよね!
この場合コントローラーでストロングパラメーターを定義する際はusersモデルに追加すればOKです。

表示の仕方
リンクをコピーしました

上のように定義した場合、保存したファイルを表示させるには下記のように記述します。

ruby
1
user.image

ファイルの保存先の変更の仕方
リンクをコピーしました

ファイルの保存先は開発環境だとconfig/environments/development.rbに書かれています。

ruby
1
config.active_storage.service = :local

デフォルトでは上記のように保存先はローカルに設定されています。
この「local」の部分はどこで定義されているかというとconfig/storage.ymlというファイルに書かれています。

ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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

# Remember not to checkin your GCS keyfile to a repository
# google:
#   service: GCS
#   project: your_project
#   credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
#   bucket: your_own_bucket

# Use rails credentials:edit to set the Azure Storage secret(as azure_storage:storage_access_key)
# microsoft:
#   service: AzureStorage
#   storage_account_name: your_account_name
#   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
#   container: your_container_name

# mirror:
#   service: Mirror
#   primary: local
#   mirrors: [ amazon, google, microsoft ]

これをみるとlocalの時は使用するサービスがDisk、つまりローカルのディスクになっています。
Active Storageではローカルの他にも様々なサービスを指定することができます。
コメントアウトされている部分をみるとAWSのS3、googleのGCS、microsoftのAzureStorageも使うことができます。
使う場合はこちらのコメントアウトを外し、Gemfileに対応したgemを追加する必要があります。

  • AWS : aws-sdk-s3
  • google: google-cloud-storage
  • microsoft: azure-storage
ruby
1
2
# 例 Gemfileに追記
gem 'aws-sdk-s3'

S3に画像を保存させる
リンクをコピーしました

herokuでActive Storgeを使用する場合、ローカルだとherokuの仕様上保存されても24時間経つかインスタンスが再起動されると消えてしまうので、S3などの外部サービスを使う必要があります。
ですので実際にAWSのS3というサービスを使って画像を保存させる設定をしてみましょう。
S3は基本的に、ファイルをアップロードし、そのURLを取得できるAWSのストレージサービスです。
まずはactive strageをS3に対応させるため、各種ファイルの編集を行います。

1. config/storage.ymlの編集
リンクをコピーしました

ruby
1
2
3
4
5
6
amazon:
  service: S3
  access_key_id: <%= ENV['ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['SECRET_ACCESS_KEY'] %>
  region: リージョンコードの指定
  bucket: バケット名

amazonの行をコメントアウトを外し、コードを反映させるようにします。
access_key_idとsecret_access_keyは環境変数で指定します。

regionは下記のページで確認をします。
https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html

bucketは自分で作成したバケット名を指定しましょう。
どちらもクオテーションで囲う必要はありません。

2. 環境変数を設定しよう
リンクをコピーしました

ターミナルで下記のコマンドを実行します。

shell
1
2
3
$ echo export ACCESS_KEY_ID="CSVに記載されているaccess_key_idカラムの値" >> ~/.bash_profile
$ echo export SECRET_ACCESS_KEY="CSVに記載されているsecret_access_keyカラムの値" >> ~/.bash_profile
$ source ~/.bash_profile

herokuにアプリをデプロイする場合は下記のコマンドでherokuのサーバーに環境変数を設定できます。

shell
1
2
$ heroku config:set ACCESS_KEY_ID="CSVに記載されているaccess_key_idカラムの値"
$ heroku config:set SECRET_ACCESS_KEY="CSVに記載されているsecret_access_keyカラムの値"

3. 開発環境でS3を使えるようにする
リンクをコピーしました

config/environments/development.rbを編集し、開発環境でS3が使えるよう変更をします。
31行目のコードを「local」から「amazon」に変更します。

ruby
1
config.active_storage.service = :amazon

4. 本番環境でS3を使えるようにする
リンクをコピーしました

config/environments/production.rbを編集し、本番環境でS3が使えるよう変更をします。
42行目のコードを「local」から「amazon」に変更します。

ruby
1
config.active_storage.service = :amazon

5. aws-sdk-s3というgemの追加
リンクをコピーしました

Gemfileに下記のコードを追記し、bundle installをします。

ruby
1
gem 'aws-sdk-s3'

これでS3の登録がしっかりとできていれば画像はS3にアップロードされます。

まとめ

Active Storageはファイルアップロードを簡単に実装できるgemです。 ローカルだけでなく、外部サービスも設定することができます。