【Rails】Devise、ActiveStorage、S3でユーザーアバターの実装


概要

タイトルの通りです。
事前にActionTextを使用していた関係で一部手順が抜けている部分もあるかもしれませんがご了承ください。
CarrierWaveを使用した記事も書いたのですが、ActiveStorageの方が何かと便利そうです。
【Rails】Devise、CarrierWave、S3でユーザーアバターの実装

環境

Ruby: 2.7.1
Rails: 6.0.2.2
Devise導入済み
(gem 'devise', '~> 4.7', '>= 4.7.1')

手順

今回は「avatar」という名称で実装してますが好みでimageなどに変更してください。

ActiveStorageのインストール

以下の手順で「active_storage_attachments」と「active_storage_blobs」の二つのテーブルが作成されます。

$ rake active_storage:install

# DBマイグレーション
$ rake db:migrate

モデルの設定

これで画像が「active_storage_attachments」テーブルの「record_type」カラムに「User」で保存されるようになります。
今回は1枚の画像のみ保存できればいいので「has_one_attached」としています。
複数枚保存する方法もありますがそちらは別記事に譲ります。

app/models/user.rb
class Comment < ApplicationRecord
  has_one_attached :avatar
end

Deviseのstrong parametersを追加

今回は編集画面でのみアバターを設定できるようにします。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
    # deviseのpermitted_parameterを追加する
    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:account_update, keys: [:avatar] )
      # 登録時も必要であればsign_upを追加
      # devise_parameter_sanitizer.permit(:sign_up, keys: [:avatar] )
    end
end

S3の設定

こちらの記事を参考にしてください。
Railsでaction text(active storage)の画像保存先をaws s3に変更した

アバターの保存と表示

アバター保存画面

app/views/users/registrations/edit.html.erb
<%= form_with model: @user, url: user_registration_path, local: true do |f| %>
  <div class="field">
    <%= f.label :avatar %>
    <%= f.file_field :avatar %>
  </div>

  <div class="actions">
    <%= f.submit "保存" %>
  </div>
<% end %>

アバター表示画面

<% if @user.avatar.attached? %>
   <%= image_tag @user.avatar %>
<% end %>

画像が表示されない場合

image_processingをインストールしてみてください。

Gemfile
# rails6であればすでにあるとおもうのでコメントアウトを外してください。
gem 'image_processing', '~> 1.2'
$ bundle

後書き

こちらの記事を参考にすれば保存した画像の整形なども簡単にできます。
Active StorageのVariantの指定方法いろいろ

冒頭に書いたように最初はCarrierWaveを使用していたのですが、それだとS3のパブリックアクセスブロックをオフにしてURLからアクセスできるようにしなければならなかったのでActiveStorageの使用に切り替えました。
設定もこちらの方が楽でした。

参考

Active Storage の概要
【Rails 5.2】 Active Storageの使い方