はじめに
現在勉強の一環で作成中の音楽レビューアプリでActiveStorageによる画像アップロードを使用したのでメモ。
アプリについて
・作成中のアプリは音楽アルバムのレビューアプリ。
・ActiveStorageを利用し、Recordモデルに画像を :jacket
として 紐づける。
#ActiveStorageのインストール
以下のコマンドでインストールする。
rails active_storage:install
#Recordモデルを編集
次にRecordモデル編集し、一つの画像を持つようにする。
今回はアルバムのジャケットとして :jacket
とする。
class Record < ApplicationRecord
has_one_attached :jacket
#以下省略
end
そしてdb:migrate
する。
#Recordにジャケットを紐づける
次にRecord新規作成(編集)のページにファイルアップロードをするタグを追加。
<%= form_with(model: @record, local: true) do |f| %>
<div class="form-group">
<%= f.label :jacket %>
<%= f.file_field :jacket %>
</div>
<%# 省略 %>
<%= f.submit "Create Record", class: "btn btn-info" %>
<% end %>
次はフォームを正しく受け取れるように records_controller
のストロングパラメータに :jacket
を追加する。
class RecordsController < ApplicationController
#省略
private
def record_params
params.require(:record).permit(:name, :artist, :release_year, :genre_id, :jacket)
end
end
#ビューで表示
ビューでは<%= image_tag record.jacket %>
のように書くことで画像を表示できるが、このままだとアップロードされた画像サイズがバラバラなのでリサイズできるようにする。
mini_magickのインストール
まずはGemfileにMiniMagickを追加。
gem 'mini_magick'
そしてbundle install
する。
##実際に表示する
先ほどMiniMagickを追加したことにより、
<%= image_tag record.jacket.variant(resize:'120x120') %>
のようにして画像をリサイズして表示できる。
<% @records.each do |record| %>
<div class="album text-center">
<%= link_to record do %>
<div class="mb-2">
<%# ここに表示 %>
<%= image_tag record.jacket.variant(resize:'120x120') %>
</div>
<h5 class="mb-0 font-italic"><%= record.name %></h5>
<% end %>
<small><%= link_to record.genre.name, records_path(genre: record.genre.name) %></small>
<p class="text-bold"><%= record.artist %></p>
</div>
<% end %>
これで画像が表示される。
#N+1問題
これまでで画像の表示は完了したがN+1問題が発生していたので修正する。
Records/index ページで一覧を表示する時に、:jacket
画像を読み込むためRecordの数だけDBに問い合わせているのが問題。
これを解決するためにはrecords_controller
を編集する。
class RecordsController < ApplicationController
def index
#省略
@records = Record.all.includes(jacket_attachment: :blob)
#省略
end
end
Record.all
と書いていたところを、
Record.all.includes(jacket_attachment: :blob)
とすることで解決した。