画像アップロード機能
画像アップロード機能の実装にはまず、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
この記事が気に入ったらサポートをしてみませんか?