Rails6 ActiveStorageでS3に保存し確認するまで


はじめに

railsでwebアプリケーションを作成する際にs3に画像を保存したいと思うことがあったので、備忘録として残します。

開発環境

windows10
rails 6.1.3.1
vscode
aws s3のセットアップについては完了しているものとします。

Active Storageのセットアップ

コンソールで下記を入力します。
$ rails active_storage:install
$ rails db:migrate

Active Storageのサービスはconfig/storage.ymlで宣言します。アプリケーションが使うサービスごとに、名前と必要な構成を指定します。
デフォルトでamazon:からのコードがコメントアウトされていたらコメントアウトを外してください。
この際のインデントに注意!
(コメントアウト無効時にインデントがずれてしまい、エラーの原因になります。筆者はこれに築かず小一時間さまよいました。)

config/storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

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: 作成したパケットのリージョン名
  bucket: s3で作成したパケット名

acces_key_id,secret_access_keyについてはIAMで権限を与えた際に控えたものをcredentials.ymlに記述
$ rails credentials:edit

aws:
  access_key_id: 控えたもの
  secret_access_key: 控えたもの

次に利用するサービスをActiveStorageに認識させますが、ここは開発環境ごとにファイルが異なります。
今回はdevelopment環境でs3を利用したので、:amazonを記述します。

config/environments/development.rb

 config.active_storage.service = :amazon

Gemfileに以下のコードを追加する
gem "aws-sdk-s3", require: false
その後以下実行
$ bundle install

以上で環境は整いました。あとは実際にModel,View,Controllerを書いて確認します。

ファイルをレコードに添付

今回はuserモデル,userコントローラーとformを利用してs3に画像を保存してみます。
自身で作成する際は対応するものに書き換えてください。

まずはuserモデルにavatarを持たせます。

has_one_attachedマクロは、レコードとファイルの間に1対1のマッピングを設定します。各レコードには1つのファイルを添付できます。

user.rb
class User < ApplicationRecord
    has_one_attached :avatar
end

次にuserコントローラーを設定
userモデルにnameとageをもっているのでそれらも一緒に受け取り保存します。

user_controller.rb
class UserController < ApplicationController
    def index 
    end

    def create
        user = User.create!(user_params)
        redirect_to root_path
    end

    private
        def user_params
          params.permit(:name, :age, :avatar)
        end
end

routes.rbにresources :userを追加してください。
最後にformを作成します。
avatarのformはform.file_field

user/index.html.erb
<%= form_with model: @user ,local: true do |form| %>

  <p>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </p>

  <p>
    <%= form.label :age %><br>
    <%= form.text_field :age %>
  </p>

  <p>
    <%= form.label :avatar %><br>
    <%= form.file_field :avatar %>
  </p>

  <p>
    <%= form.submit %>
  </p>

<% end %>

以降、サーバーを起動後
localhost:3000/userで下記のような画面が出るので画像選択しを送信するとs3に保存されます。

以上!お疲れさまでした。

参考

Railsガイド(Active Storageの概要)
Railsガイド (Railsを始めよう)