[Rails] deviseにActiveStorageを用いてユーザーのアイコンを設定する


はじめに

本記事に従えば、deviseでのユーザーのアイコンを設定できます。
保存先としてAWSのS3を利用しています。

手順

① ActiveStorageをインストールする
② 保存作の変更(AWS S3)
③ Userモデルとの関連付け
④ アップロードと表示

ActiveStorageをインストールする

$ rails active_storage:install
$ rails db:migrate

このコマンドでActiveStorageがインストールされ、データベースにactive_storage_attachments, active_storage_blobs, active_storage_variant_recordsが追加されます。

保存先の変更

保存先にはAWSのS3を使います。
AWSのアクセスキーIDとシークレットキーを環境変数にするため、Gemfileに以下を追加します。
アクセスキーとシークレットキーを取得する方法は、下記を参考にしてください。

Gemfile.
gem 'dotenv-rails'
bundle install

次に.envファイルを用意し、環境変数を設定していきます。

env.
MY_ACCESS_KEY_ID='アクセスキーID'
MY_SECRET_KEY_ID='シークレットキー'

GitHubを利用している方は、このファイルをリポジトリに上げないために、

gitignore.
/.env 

を追記してください。

次に保存先を変更します。

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, "ENV['MY_ACCESS_KEY_ID']") %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, "ENV['MY_SECRET_KEY_ID']") %>
  region: リージョン名
  bucket: バケット名
config/environments/development.rb
# :localから:amazonに変更することで、先ほど定義したamazon:を読み込みさせる。
config.active_storage.service = :amazon

AWS用のGemを追加します。

Gemfile.
gem 'aws-sdk-s3', require: false
bundle install

Userモデルとの関連付け

user.rb
#省略
  has_one_attached :avatar # 追加

アップロードと表示

avatarをアップロードするため、deviseのストロングパラメーターを変更します。

application_controller.rb
  def configure_permitted_parameters
    # devise_parameter_sanitizer.permit(:sign_up, keys: [ :avatar] )  signupするときも設定したい場合はコメントアウトを消してください
    devise_parameter_sanitizer.permit(:account_update, keys: [ :avatar])
  end
registration_controller.rb
  def update
    super
    if account_update_params[:avatar].present?
      resource.avatar.attach(account_update_params[:avatar])    
    end
  end

これでユーザー情報を編集する際にavatarを設定できるようになりました。
実際にavatarを設定するためにviewを変更します。

views/registrations/edit.html.erb
#追加

<div class="field">
  <%= f.file_field :avatar %>
</div>

表示したい時は

<%= image_tag rails_blob_path(@user.avatar) %>

を任意のviewに追加してください。