LoginSignup
1
0

More than 3 years have passed since last update.

【Rails】ActiveStorageによる画像アップロード

Last updated at Posted at 2021-04-13

はじめに

 現在勉強の一環で作成中の音楽レビューアプリでActiveStorageによる画像アップロードを使用したのでメモ。

アプリについて

・作成中のアプリは音楽アルバムのレビューアプリ。
・ActiveStorageを利用し、Recordモデルに画像を :jacket として 紐づける。

ActiveStorageのインストール

以下のコマンドでインストールする。

   rails active_storage:install

Recordモデルを編集

次にRecordモデル編集し、一つの画像を持つようにする。
今回はアルバムのジャケットとして :jacket とする。

app/models/record.rb
class Record < ApplicationRecord
  has_one_attached :jacket

 #以下省略
end

  
そしてdb:migrateする。

Recordにジャケットを紐づける

次にRecord新規作成(編集)のページにファイルアップロードをするタグを追加。

app/views/records/_form.html.erb
<%= 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 を追加する。

app/controller/records_controller.rb
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を追加。

Gemfile
    gem 'mini_magick'

そしてbundle installする。
  

実際に表示する

先ほどMiniMagickを追加したことにより、
<%= image_tag record.jacket.variant(resize:'120x120') %>
のようにして画像をリサイズして表示できる。

app/views/records/index.html.erb
<% @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を編集する。

app/controller/records_controller.rb
class RecordsController < ApplicationController

  def index
    #省略
  @records = Record.all.includes(jacket_attachment: :blob)
    #省略
  end

end

Record.allと書いていたところを、
Record.all.includes(jacket_attachment: :blob)
とすることで解決した。

1
0
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
1
0