25
19

More than 3 years have passed since last update.

deviseとActive Storage を使ってavatar(アイコン)登録する

Last updated at Posted at 2020-03-10

Active Storageの場合 (Rails 5.2以降の場合)

アクティブストレージは保存場所を信頼性の高いamazon, google, microsoftが提供するクラウドに保存できる。またバックアップもできるので、データが消えた場合などに非常に重宝されます。

設定方法も非常に簡単です。

概要
Active StorageによるRails ファイルアップロード
Active Strageを使用してユーザーのアバターを登録、表示する
参考になるページ
【Rails 5.2】 Active Storageの使い方

ターミナル
$ rails active_storage:install
$ bundle exec rake db:migrate

rails active_storage:installコマンドを実行すると、active_storage_blobs と active_storage_attachmentsテーブルが生成されるのでこちらをモデルに反映させるためrails db:migrateする

作成されたテーブルは下記の役割となります。

テーブル 機能
active_storage_blobs アバター画像の保存先
active_storage_attachments userとavatorの中間テーブル

ローカル環境、テスト環境、本番環境で保存先を変更する。
storage.ymlで設定を変えていく

config/storage.yml
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 ]

すでにamazonの記述はあります。なので,amazonのs3で保存する場合はコメントアウトを解除して下記のようにします。

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, "YOUR ACCESS_KEY_ID") %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, "YOUR SECRET_ACCESS_KEY") %>
  region: ap-northeast-1 # 東京の場合(海外の場合異なります)
  bucket: バケット名

config/environments/production.rb
# :localから:amazonに変更することで、先ほど定義したamazon:を読み込みさせる。
config.active_storage.service = :amazon

AWS用のGemを追加します

Gemfile
gem 'aws-sdk-s3', require: false

userモデルとavatorを紐づける

user.rb
class User < ApplicationRecord
  #Include default devise modules. Others available are:
  #:confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_one_attached :avatar # 追加
end

このアクセサに、Active Strageがファイルをアタッチしてくれます。
なお、レコードとファイルが1対1の場合は has_one_attached ですが、1対多の場合は has_many_attached になります。

form
= f.file_field :avatar

これで登録可能です。

編集の場合

今回はgem "devise"を利用してアイコンを登録する場合です。

deviseのparamsを指定するために、application_controllerでaccount_updateの記述を追加します

application_controller.rb
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [ :avatar] )
    devise_parameter_sanitizer.permit(:account_update, keys: [ :avatar])
  end

これでparamsにavatarが読み取れます。
つづいて、active_strageで保存する場合、

親要素.イメージ名.attach(params[:key]

とする必要があります。
例えば,既存のuserにavatarを付与するには

User.avatar.attach(params[:avatar])

とします。
.attachメソッドで追加/更新しなければいけないのがポイントです。
ですから、通常通りupdateするだけでは更新されません。
update処理に.attachを追加します。今回はdeviseということなので、deviseのregistration_controller.rbに処理を追加します。コメントアウトを解除して、下記の処理にします。

registration_controller.rb
  def update
    super
    if account_update_params[:avatar].present?
      resource.avatar.attach(account_update_params[:avatar])    
    end
  end

これでavatarが付与/更新されます。

参考資料

[Rails][devise] devise + active_recordで画像を編集する
バリデーションの設定

25
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
19