続・ActiveStorageを使って、画像投稿機能実装までの流れ


はじめに

 ActiveStorageを使った画像保存から表示までの説明。前回の投稿で、ActiveStorageの導入方法については説明している。

リンク↓
ActiveStorageを使って、画像投稿機能実装までの流れ

画像の保存から表示までの流れ

  1. アソシエーションの定義
  2. ストロングパラメーターに画像保存の許可をする
  3. HTMLのimg要素として生成
  4. エラーの解消
  5. 画像の大きさ調整
  6. バリデーションの設定

1. アソシエーションの定義

has_one_attachedメソッドを用いて、各レコードと画像ファイルを1対1の関係で紐づける。
紐づけたいモデルファイルに記述

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

ファイル名には、呼び出す際の名前を設定する。また、パラメーターのキーになる。
ex):image, :file etc
イメージとしては、ファイル名のカラムができて、そこに添付ファイルが入っているような感じ。
このアソシエーションをすることで、
モデル名.ファイル名で添付したファイルにアクセスすることができる。

2. ストロングパラメーターに画像保存の許可をする

controllers
 params.require(:message).permit(:text, :image)

アソシエーションの定義のときにも取り上げたように、パラメーターのキーにファイル名を用いる。このときにも、カラムができているイメージというのは当てはまるだろう。

以上が、保存までの流れ。

以下は、表示するまでの流れ。

3. HTMLのimg要素として生成

image_tagメソッドというヘルパーメソッドを用いて、HTMLにimgタグを生成する。

html.erb
<%= image_tag モデル名.ファイル名 %>
<%= image_tag message.image %>  #例

アソシエーションしているため、モデル名.ファイル名だけの記述で画像を表示させられる。

基本的にはここまでで、画像を表示できる。しかしこのままでは、画像が必ずなければ、エラーになってしまう。

4. エラーの解消

 先のimage_tagメソッドにif文で条件分岐させる。

html.erb
<%= image_tag message.image, if message.image.attached? %>

attached?メソッド で画像が添付されていると、trueを返し、読み込まれる。画像が添付されていないと、falseを返し、読み込まれず、エラーが起きない。

5. 画像の大きさ調整

ActiveStorageを導入していると使えるメソッドのvariantメソッドを使う。
先のコードに付け足すと、

html.erb
<%= image_tag message.image.variant(resize: '500×500'), if message.image.attached? %>

画像の表示サイズを指定すると、それ以上に大きくならない。

6. バリデーションの設定

現状だと、LINEをイメージすると、テキストと画像が必ず両方ないとエラーになる。使い勝手がよくないため、テキストと画像のどちらかが存在すればよい、という仕様にする。

model
validates :message, presence: true, unless: :was_attacher?

def was_attached?
 self.image.attached?
end

メソッドの返り値がfalseならば、バリデーションの検証を行う。(messageが存在しないとダメ)

最後に

アソシエーションするだけで、簡単に画像にアクセスできるのが便利すぎる!!