##Active Storageはファイルアップロードを簡単に実装することができる機能。
ローカル環境では、ローカルディスクに保存し、本番ではS3などに保存することも出来るらしいです。
保存先はconfig/strage.ymlで確認できます。
導入方法は以下のコードをコマンドで実行します。
$ rails active_storage:install
すると一つのマイグレーションファイルが生成されます。
中身の例↓
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
t.string :key, null: false
t.string :filename, null: false
t.string :content_type
t.text :metadata
t.bigint :byte_size, null: false
t.string :checksum, null: false
t.datetime :created_at, null: false
t.index [ :key ], unique: true
end
create_table :active_storage_attachments do |t|
t.string :name, null: false
t.references :record, null: false, polymorphic: true, index: false
t.references :blob, null: false
t.datetime :created_at, null: false
t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
end
このファイルの詳細はよく理解できていませんが、どうやら二つのテーブルを作成できる様なので。
↓実行。
$ rails db:migrate
すると「active_storage_attachments」と「active_storage_blobs」という二つのテーブルが作成されます。
・blobsは簡単に言うとデータの名前やサイズなどのデータ情報を保存するテーブル。
・attachmentsは画像を投稿したいモデルのモデル名などを保存するテーブル。
仮にuserモデルに画像を投稿したいとすると、
###userモデル → attachments → blobs
みたいな感じで関連性が紐づけられるみたいです。
実際に紐づけるにはuserモデルを例に使います↓
class User < ApplicationRecord
# 1対1(単数枚画像投稿)で関連付ける場合
# :imageとありますが名前は:hogehogeなど指定は自由です。
has_one_attached :image
# 1対多(複数枚画像投稿)で関連付ける場合
has_many_attached :images
end
上記のコードを書くと裏側で関連付けされて
新しく色々なメソッドが使える様になります。
usersテーブルに新しくimageカラムを追加したりはしなくて大丈夫です。
(Active Storageが裏側で色々やってくれているみたいです)
例えば
#フォームから画像データが送られてきたら、attachメソッドを使いimage属性にデータを添付します。
user.image.attach(paramsデータ)
#アップされた画像を描画することができる。
#attachしてなければ何も表示されない。
user.image
#userオブジェクトに画像があるか論理値を返す。
user.image.attached?
###モデルのデータベースに保存されるわけではない。
仮にuserのデータベースに名前、メールアドレス、プロフィール画像を保存するとしたら
@user.saveで画像も保存されているように見えますが実際にはuserのデータベースには画像の情報は保存されないようです。
画像の情報はあくまで、**「active_storage_attachments」と「active_storage_blobs」に保存されて、「has_one_attached :image」**によってuserモデルと二つのテーブルは関連付けされているので、userオブシェクトを通して画像を引っ張ってこれる様なイメージです。
def create
@user = User.new(user_params)
@user.image.attach(params[:user][:image])
@user.save
end
def user_params
params.require(:user).permit(:name, :email,:image)
end
素人なりに簡単にまとめてみましたが、間違っている箇所がありましたら、ご指摘いただけると幸いです。