画像アップロード機能

画像アップロード機能の実装にはまず、RailsのActive Storageという機能を使用。画像の保存・表示・サイズの調整ができる。

・Active Storage

ファイルアップロード機能を簡単に実装できるGem。Railsに統合された。

Active Storageを使うと、画像などのファイルのアップロードを簡単にするメソッドが使用でき、画像を保存するテーブルを簡単に作成できる。

______________________

Active Storageでファイルをアップロードして保存した後、画像を加工してから(サイズや色など)表示できるように実装する。

・・・画像加工のために必要なImageMagickという画像変換ツールと、それをRailsから使うためのGemをインストールする。

・ImageMagick

コマンドラインから画像に処理を加えることができるツール。
画像の作成やサイズ変更、保存形式の変更などの処理ができる。

______________________

ImageMagickはGemではなく、Homebrewからインストールするソフトウェア。

・・・GemではないImageMagickをRubyやRailsで扱うには、MiniMagickとImageProcessingというGemを追加する必要がある。

・MiniMagick

ImageMagickの機能をRubyで扱えるようにしてくれるGem。

・ImageProcessing

MiniMagickでは提供できない、画像サイズを調整する機能を提供するGem。

______________________

まずはImageMagickをHomebrewからインストール。

% brew install imagemagick

続いて、MiniMagickとImageProcessingをインストール。Gemfileに追記する。

# Gemfileの一番下に記述する

gem 'mini_magick'
gem 'image_processing', '~> 1.2'
% bundle install

Active Storageをアプリケーション内で使用する準備。

% rails active_storage:install      # Active Storageに関連したマイグレーションが作成

% rails db:migrate                  # 続けてマイグレート

______________________

作成したActive Storageのテーブルに、画像を保存するための実装を行う。

・Active Storageのテーブルとフォームの内容を保存するテーブルとのアソシエーションを定義
・コントローラにて、imageカラムの保存を許可

・has_one_attachedメソッド

各レコードとファイルを1対1の関係で紐づけるメソッド。
has_one_attachedメソッドを記述したモデルの各レコードは、それぞれ1つのファイルを添付できる。

class モデル < ApplicationRecord
 has_one_attached :ファイル名
end

":ファイル名" には、添付するファイルがわかる名前をつけましょう。
この記述により、"モデル.ファイル名" で、添付されたファイルにアクセスできる。
このファイル名は、そのモデルが紐づいたフォームから送られるパラメーターのキーになる。

______________________

・image_tagメソッド

img要素を生成するRailsのヘルパーメソッド。

複雑なRailsのディレクトリパスを指定しなくても、モデルから画像ファイルを呼び出して引数に記述するだけで、画像を表示するimg要素を生成する。

# ファイルをモデルから指定する場合
<%= image_tag モデル.画像ファイル %>
<%= image_tag user.avatar %>

# app/assets/ディレクトリ下の画像ファイルパスでも指定できる
<%= image_tag 画像ファイルのパス %>
<%= image_tag "avatar.png" %>

画像が存在しない場合でも、画像を表示する記述が読み込まれて、エラーを引き起す。・・・attached?メソッドを使用。

・attached?メソッド

レコードにファイルが添付されているかどうかで、trueかfalseを返すメソッド。

<%= image_tag message.image, class: 'message-image' if message.image.attached? %>

・variantメソッド

ファイルの表示サイズを指定できる。Active Storageを導入している場合に使用可能なメソッド。指定された横幅と高さを超えるサイズにはならない。

モデル.ファイル名.variant(resize: '幅x高さ')      # x(エックス)を使用

______________________

補足:バリデーションを変更し、画像かテキストどちらかが存在していれば、メッセージを送信できるように実装。

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

 validates :content, presence: true, unless: :was_attached?

 def was_attached?
   self.image.attached?
 end
end

validatesのunlessオプションにメソッド名を指定:
「メソッドの返り値がfalseならばバリデーションによる検証を行う」という条件。

was_attached?メソッド:self.image.attached?という記述によって、画像があればtrue、なければfalseを返す。

2020/11/08

この記事が気に入ったらサポートをしてみませんか?