エンジニア転職日記

エンジニア転職に向けての日記です

How to ActiveStorage

概要

オリジナルアプリ作成において、画像の投稿機能が必要になったのでここにアウトプットしておきます。

ActiveStorageとは

ActiveStorageは、ファイルアップロードを簡単に実装できるGemです。この機能を使うと、画像の保存、表示、サイズ調整が簡単に行えます。

使い方

事前準備

ActiveStorageで画像をアップロードするには、画像を加工するツール、それをRailsから呼び出すツールをインストールする必要があります。

ImageMagick

ImageMagickは、コマンドラインから簡単に画像の保存形式の変更などが行えるツールです。

image_processing

image_processingは、画像のサイズを調整してくれるGemです。

 

mini_magick

ImageMagickRailsから呼び出すためのツールです。

 

これらをインストールしていきます。

 

まずは、brewからImageMagickをインストールします。

% brew install imagemagick

 

続いて、mini_magick、image_processingをインストールします。

# Gemfile

gem 'mini_magick'
gem 'image_processing', '~> 1.2'

bundle install、サーバー再起動をしたらインストール完了です。

 

次は、ActiveStorageをアプリケーション内で使用できるようにします。

% rails active_storage:install

このコマンドを実行すると、ActiveStorageに関連したマイグレーションファイルが作成されます。マイグレートして情報を反映させましょう。

% rails db:migrate

 

これでActiveStorageが使えるようになりました。

 

保存機能の実装

作成したActiveStorageのテーブルに画像を保存するための実装を行います。

今回は、チャットルームのアプリケーションを例にしているので、作業工程は以下のようになります。

・ActiveStorageのテーブルとMessagesテーブルのアソシエーションを記述する

・messages_controller.rbにてimageカラムの保存を許可する

 

Messagesテーブルのレコードと画像を紐付けるためにhas_one_attachedというメソッドを利用します。has_one_attachedのアソシエーションを記述すると、各レコードと画像ファイルを1対1の関係で紐づけることができます。つまり、1つのメッセージにつき1枚の画像を保存できるということです。

 

messages.rbを開いて以下のように記述します。

class Message < ApplicationRecord
  belongs_to :room
  belongs_to :user
  has_one_attached :image

  validates :content, presence: true
end

 

さらに、messages_controller.rbのストロングパラメーターにてimageカラムの許容を記述します。

  private

  def message_params
    params.require(:message).permit(:content, :image).merge(user_id: current_user.id)
  end

 

表示機能の実装

画像表示部分のhtmlを編集します。

  <div class="lower-message">
      <div class="message-content">
      <!-- 投稿したメッセージ内容を記述する -->
        <%= message.content%>
      </div>
      <%= image_tag message.image, class: 'message-image' %>
  </div>

このように記述すると、画像を表示できるようになります。

しかし、このままでは画像がない場合でも、画像を表示する機能が読み込まれ、エラーが発生してしまいます。エラーハンドリングの記述を行います。

<div class="lower-message">
    <div class="message-content">
    <!-- 投稿したメッセージ内容を記述する -->
      <%= message.content%>
    </div>
    <%= image_tag message.image, class: 'message-image' if message.image.attached? %>
</div>

 

これで画像の表示ができるようになりました。

続いて、表示画像の大きさを調節する機能を実装します。

 

variantメソッド

variantメソッドはActiveStorageを導入している時に使用可能なメソッドです。variantメソッドを使用することで、ビュー側で使用したいサイズをその都度指定できます。

 

画像表示部分のhtmlを再度編集します。

<div class="lower-message">
    <div class="message-content">
    <!-- 投稿したメッセージ内容を記述する -->
      <%= message.content%>
    </div>
    <%= image_tag message.image.variant(resize:'500x500'), class: 'message-image' if message.image.attached?%>
</div>

これで、アップロードした画像が指定した大きさで表示できるようになりました。