はじめに
この記事では、RailsのActiveStorageを用いてAmazon S3に画像をアップロードし、その機能をHerokuで正常に動作させる方法を説明します。
S3を活用することで、アプリケーション側の負担を減らし、より高いパフォーマンスを発揮することができます。
前提条件
Rails 7.0.6
Ruby 3.2.2
アプリケーションがすでにHerokuにデプロイされており、AWSアカウントは作成済みとします。
ActiveStorage
ActiveStorageは、Rails 5.2
から導入された、アプリケーション内でファイルアップロードを簡単に扱うことができる機能です。
ユーザーからアップロードされたファイルを、データベースではなくクラウドストレージやローカルのファイルシステムに保存することができます。
ActiveStorageのセットアップ
テーブル作成
ActiveStorageはアップロードされたファイルを直接モデルのテーブルに保存しません。
代わりに、active_storage_blobs
テーブルにファイルのメタデータを保存し、active_storage_attachments
テーブルを使用して該当するモデルとの関連を作ります。
なので、まずは代わりになるテーブルを作成していきます。
rails active_storage:install
このコマンドを実行すると代わりのテーブルを作成するためのマイグレーションが生成されます。
rails db:migrate
コマンドを実行し、テーブルを作成します。
マッピング
ファイルを添付したいテーブルのモデルファイルに、作成されたテーブルとの紐づけを行います。
たとえば、Userモデルがあるとして、各ユーザにアバター画像を添付したい場合は、以下のように定義します。
こうすることで、レコード1件ごとに1個のファイルを添付できます。
class User < ApplicationRecord
has_one_attached :avatar
end
複数添付したい場合は、以下のように記述します。
class User < ApplicationRecord
has_many_attached :avatars
end
これでセットアップは完了となり、ファイルが作成されたテーブルに保存されるようになります。
S3のセットアップ
バケット作成
S3からバケットを作成します。
設定はリージョンが自分の地域に設定されているかどうかを確認し、それ以外はデフォルトのままで問題ありません。
バケットは開発
、テスト
、本番
用の全部で3つ設定します。
このとき、名前の付け方は下記のようにしてください。
- myawsbucket-development
- myawsbucket-production
- myawsbucket-test
IAMポリシーの作成
IAMユーザでの必要なアクセス制御を追加したポリシーを作成します。
IAM>ポリシー>ポリシー作成に進んでいき、S3を選択します。
選択したら、必要なアクションにチェックをつけます。
必要なアクションは全部で4つあります。
- ListBucket
- PutObject
- GetObject
- DeleteObject
この4つにチェックをつけたうえで、ポリシーを作成してください。
IAMユーザの作成
IAM>ユーザ>ユーザの作成に進みます。
許可を設定する際には、『ポリシーを直接アタッチする』を選択し、作成したポリシーを選択してください。
以降はデフォルトのままで問題ありません。
ユーザを作成したら、アクセスキーを作成します。
作成したユーザの『セキュリティ認証情報』タブに切り替え、アクセスキーを作成を押します。
ユースケースには『AWSの外部で実行されるアプリケーション』を選択します。
アクセスキーを作成したら、アクセスキーとシークレットアクセスキーをコピーしておきます。
ここまでがS3のセットアップになります。
ActiveStorageとS3の連携
config/storage.yml
の編集
コメントアウトを外してregionを自分の地域に変更します。
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: ap-northeast-1
bucket: myawsbucket-<%= Rails.env %>
bucketに<%= Rails.env %>を使うことで、開発環境では『development』、テスト環境では『test』、本番環境では『production』となり、それぞれの環境ごとのバケットにファイルがアップロードされます。
それからターミナルを開き、VScodeでcredentials.ymlファイルを開くコマンドを実行します。
EDITOR="code --wait" rails credentials:edit
このファイルにawsのアクセスキーとシークレットアクセスキーを追加します。
# aws:
# access_key_id: 123
# secret_access_key: 345
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: ********
aws:
access_key_id: ********
secret_access_key: ********
ちなみにcredentialsとは、Railsが提供する暗号化された設定ファイルなので、シークレットキーなどの重要な情報はここに設定しましょう。
環境ファイルの編集
config/environments/development.rb
config/environments/production.rb
それぞれのファイルの下記を変更します。
config.active_storage.service = :amazon
Gemのインストール
Gemfileに下記を追加します
gem "aws-sdk-s3", require: false
追加したらbundle install
を忘れずに行いましょう。
Herokuのセットアップ
設定したファイルをすべてpushし、デプロイします。
デプロイが終わったら、環境変数を設定します。
ターミナルに下記のコマンドを入力してください。
heroku config:set AWS_ACCESS_KEY_ID="********"
heroku config:set AWS_SECRET_ACCESS_KEY="="********""
設定し、heroku config
でキーが確認できれば連携は完了し、ファイルがS3にアップロードされるようになります。
参考資料