初学者の備忘録
初学者の備忘録です。前に投稿した画像投稿の発展、画像複数投稿編
参考にした記事
注意
前回の画像投稿はプレビュー機能も一緒に載せてましたが、今回は複数投稿なのでプレビューは表示できません。これから挑戦しようと思います。
実装
【1】 アソシエーション
元々あったアソシエーションは単数なので複数に対応したアソシエーションに変更します。
:
:
# 単数投稿
- has_one_attached :image
# 複数投稿
+ has_many_attached :images
:
:
【2】 ストロングパラメーター
ストロングパラメーターの定義をハッシュ形式にします。ハッシュ形式にした場合は最後に記述してください。
:
:
private
def place_params
params.require(:place).permit(
:pet,
:fee,
:start_time,
:end_time,
+imageds: []
# 前の結果に対して、付け加える
)
end
end
【3】 view
画像投稿フォームを編集します。multiple: true
で実現できます。
<%= f.file_field :images, multiple: true %>
ここまでで画像複数投稿が実装できてますが、このままだとバリデーションが設定されていないのでバリデーションを設定していきましょう。
【4】 バリデーション
今回は画像投稿枚数にバリデーションをかけます。バリデーションを設定するにあたってGemがあるのを知ったのでGemを使用して設定していこうと思います。
使用したGemはactive_storage_validationsです。
まずはGemをGemfileに記述して、インストールします。
gem 'active_storage_validations'
次にインストール
$ bundle install
これで画像関係のバリデーションGemは導入できたので、対象Modelにバリデーションを記述します。
:
:
# 画像枚数のバリデーション
validates :images, limit: { min: 0, max: 3 }
:
:
limitが個数関係のバリデーションです。
ここで私の失敗談ですが、バリデーション設定の時、最大枚数は3枚だけでよくて画像投稿しなくてもいい設定にしようとして最小値を設定しなかったのですが、最小値は設定しないといけないようでした。
おまけ
画像を複数投稿できる機能をつけたということは複数表示させるようにViewも設定しないといけません。
Viewで画像を複数表示させるにはeach文を使用します。
まずはModelで画像があるかないか判断するメソッドを設定している場合、Modelのメソッドをeach文に対応できるように設定します。
:
:
# 画像が存在するかどうか判断するメソッド
def get_place_image
# 存在しなかった場合no_image.pngを使用
# []配列にすることでeachが使用できるように設定
(images.attached?) ? images : ['no_image.png']
end
:
:
次にViewをeach文で表示させます。
:
:
<!--画像を繰り返し表示-->
<% @place.get_place_image.each do |img| %>
<%= image_tag img, alt: 'Place Image', class: 'img-fluid w-100' %>
<% end %>
:
:
Modelで文字列を配列に無理やりですが変更させてあげたことによって、Viewのコードがすっきりしたコードにできました。
:
:
<!--Modelで対応しなかった場合-->
<% if @place.images.attached? %>
<% @place.images.each do |image| %>
<%= image_tag image, alt: 'Place Image', class: 'img-fluid w-100' %>
<% end %>
<% else %><!--存在しなかった場合-->
<%= image_tag "place_no_image.png", style: "width: 50;", id: 'imagePreview', class: "img-fluid mb-3" %>
<% end %>
:
:
以上でバリデーション設定終了です。お疲れ様でした。
最後に
初めての挑戦ということもあり画像複数投稿はなかなか苦戦しました。ですが様々な発見もありました。
特にバリデーションとviewの表示は勉強になりました。やっぱりプログラミングは楽しい。
ではお疲れ様でした。