3
2

More than 1 year has passed since last update.

RailsのActive Storageについて仕組みがよくわからなかったが自分なりに解釈してみた。

Posted at

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

素人なりに簡単にまとめてみましたが、間違っている箇所がありましたら、ご指摘いただけると幸いです。

3
2
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
3
2