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で設定を変えていく
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で保存する場合はコメントアウトを解除して下記のようにします。
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: バケット名
# :localから:amazonに変更することで、先ほど定義したamazon:を読み込みさせる。
config.active_storage.service = :amazon
AWS用のGemを追加します
gem 'aws-sdk-s3', require: false
userモデルとavatorを紐づける
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 になります。
= f.file_field :avatar
これで登録可能です。
編集の場合
今回はgem "devise"を利用してアイコンを登録する場合です。
deviseのparamsを指定するために、application_controllerでaccount_updateの記述を追加します
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に処理を追加します。コメントアウトを解除して、下記の処理にします。
def update
super
if account_update_params[:avatar].present?
resource.avatar.attach(account_update_params[:avatar])
end
end
これでavatarが付与/更新されます。