ActiveStorage とはざっくり言うと
画像をDB(データベース)でイイ感じに管理してくれる、「便利なヤツ」です。
難しい仕組みは後ほど解説しますが、仕組みまで理解してなくとも簡単に使えるようになっているのが特徴で、これからActiveStorageを導入する方などは最後までお付き合いください。
導入手順
インストール
まずはターミナル等で、railsを使用しているプロジェクト(フォルダ)に移動します。
そして、次のコマンドを実行して ActiveStorage をインストールします。
rails active_storage:install
rails db:migrate
実行後は、「YYYYMMDDHHMMSS_create_active_storage_tables.active_storage.rb」というファイルが作成され、さきほどのマイグレーションの実行で、schemaファイルに以下の内容が追加されます。
モデルでの定義を追加
ActiveStorageで画像を扱うモデルに対して、以下のようにコードを追加します。
今回は、「Book」というモデルに対して導入するため、book.rbファイルに追記します。
この行は重要なので、意味を解説しておきます。
- has_one_attached
- 対象モデルのレコードと画像を単数で紐づける。(複数の場合はhas_many_attached)
- :image
- リレーションを組むカラム名のようなモノ。任意の名称でよい。
Viewファイルを編集
ここからは、実際に画像を登録できるように、画面のフォームを編集していきます。
以下のように、モデルで指定した “image” という名称で file_field を追加します。
(新規登録画面、編集画面など、必要な箇所に追加してください)
Controllerファイルを編集
最後にコントローラーを編集して、画像をDBに登録できるようにします。
今回は Book モデルに対して画像を登録するため、book_controllerの対象メソッド(createやupdateなど)に以下の記述を追加します。
このコードのミソは、”:image” の部分で、これがフォームやモデルで指定した名称と同じになっていることで、画像が登録されるようになっています。
※上のコードは、Book.new なので新規作成の例ですが、updateの場合は Book.update などの記述で出来ます。その辺りは追加する箇所に対して適切になるようにしてみてください。
ActiveStorageの動きを解説
さて、導入と動作はここまでで完了です!
ここからは ActiveStorage の理解を深めるために、登録した画像が何処にどのように登録されているか解説していきます。
※これ以降は、理解を深めたい人だけお進みください。
導入時に作られたテーブル
AcriveStorage では、画像をDBのカラムに文字列として格納し、呼び出された時に画像として表示しています。
では、そのテーブルはどのようになっているのか、インストール時に自動作成されたテーブルを見てみましょう。
schema.rb を見ることでも確認できますが、active_storage_blobs に “metadata” というカラムがあり、ここに画像が文字列のデータとして格納されています。
画像レコードとモデルの紐付けの仕組み
ここまでやってきて、理解されている方は「active_storage_attachments は1つのテーブルなのに、複数モデルで画像を扱ったらどうなるのだろう」と思うかもしれません。
結論から言うと、複数モデルで画像を扱っても active_storage_attachments 1つのテーブルだけで紐付きを管理できるんです。
実際にどんなレコードが入っているか見てみましょう。
active_storage_attachments のレコード
Bookモデルの任意のレコードに対して画像を1つ登録してみました。
この時の active_storage_attachments のレコードは以下のようになっています。
それぞれのカラムを解説すると、以下の通りです。
- name
- モデルで指定した名称。
- record_type
- モデル名
- record_id
- モデルの対象レコードのid
- blob_id
- active_storage_blobs のレコードのid
また、”created_at” のカラムしか存在しないことを考えると、このテーブルのレコードはデリート&インサートで内容を更新していると言えます。(=updateではない)
refile(画像系gem)との共存
これまで説明したActiveStorageの仕組みからすると、テーブルは独立しているため、refileなど画像系gem が既に入っていても導入可能です。
ただし、modelやviewファイルでの記載で競合する部分があるので、それらについて解説します。
refile -> ActiveStorage での競合箇所
それぞれの箇所を以下のように修正すれば、ActiveStorageで問題なく動作するようになります。
model
# refile
attachment :image
↓
# ActiveStorage
has_one_attached :image
view
# refile
<%= attachment_image_tag @book, :image, :fill, 60, 60, fallback: "no_image.jpg"%>
↓
# ActiveStorage
<% if @book.image.attached? %>
<%= image_tag @book.image, size: '60x60' %>
<% else %>
<%= image_tag 'no_image.jpg' %>
<% end %>
コメント