【Rails】 画像の複数投稿


はじめに

今回は、初めて実装した複数画像投稿の機能につきまして、自身の備忘録として、またこれから実装する初心者の方の参考になればと思い投稿していきたいと思います。

(参考記事)
・refileの基本と複数画像のアップロード
https://qiita.com/nekosuke_/items/501e7ba1b286c51c1be9

開発環境

ruby 2.6.3
Rails 5.2.4.4

見本(投稿のためアップロードした画像)

※画像自体に背景が無いので少し分かりづらいかもしれません。申し訳ありません。

今回使用するモデル

口コミサイトのように店舗情報を掲載させるということが目的でしたので、モデルはShop、ShopImage(その店舗の複数画像をアップする用)で実装しております。
また店舗情報のカラムは、最小限に省略させていただいております。

モデル名 カラム名
Shop id
name
caption
モデル名 カラム名
Shop_image id
shop_id
image_id


gemをインストール

※refile: アプリケーション向けのファイル・アップロードのライブラリ。
※refile-mini_magick: 画像のサイズを変更するためのもの。

Gemfile.
gem "refile", require: "refile/rails", github: 'manfe/refile'
gem "refile-mini_magick"
terminal.
$ bundle install


モデルを作成

複数画像用のモデルを新しく作成し、マイグレーションへ反映させます。

terminal.
$ rails g model Shop name:string caption:text
$ rails g model ShopImage shop_id:integer image_id:string
$ rails db:migrate
db/schema.rb
ActiveRecord::Schema.define(version: 2021_02_16_101010) do

  create_table "shops", force: :cascade do |t|
    t.string "name", null: false
    t.string "caption", null: false
  end

  create_table "shop_images", force: :cascade do |t|
    t.integer "shop_id", null: false
    t.string "image_id", null: false
  end

end


モデルファイルの編集

models/shop.rb
class Shop < ApplicationRecord
  has_many :post_images, dependent: :destroy
  accepts_attachments_for :post_images, attachment: :image
end
models/shop_image.rb
class Post < ApplicationRecord
  belongs_to :shop 
end


コントローラーの設定

private以下のパラメータの記述の中に複数画像の情報、shop_images_images: []を追加します。複数画像を投稿する場合は、配列として渡す必要があります。→ []

shop.contorller.rb

  def index
    @shop = Shop.all
  end

  def new
    @shop = Shop.new
  end

  def create
    @shop = Shop.new(shop_params)
    @shop.save
  end

  private
  def shop_params
    params.require(:shop).permit(:name, :caption, shop_images_images: [])
  end


Viewの作成

店舗情報を追加するための入力フォーム画面です。
複数画像の投稿には、「multiple: true」こちらの記述を加える必要があります。

shops/new.html.erb
<%= form_with model: @shop, url: shops_path, local: true do |f| %>
 <%= f.label :"店舗名"%>
 <%= f.text_field :name %>
 <%= f.label :"店舗画像"%>
 <%= f.attachment_field :shop_images_images, multiple: true %>
 <%= f.label :"紹介文"%>
 <%= f.text_area :caption %>
<% end %>

先ほども補足で記載しましたが、複数画像は配列として取得する必要がありましたので、each文で全店舗の中から1件の店舗情報を取得し、そこから1件の店舗情報に紐づく複数の画像を更にeach文で配列として取得する形になります。

shops/index.html.erb
<% @shops.each do |shop| %>
 <%= shop.name %>
 <%= shop.caption %>
 <% @shop.shop_images.each do |shop_image| %>
  <%= attachment_image_tag shop_image, :image, size: "130x130" %>
 <% end %>
<% end %>

こちらの手順で、先ほどの見本のような複数投稿が可能になりました!

終わり

今回は以上になります。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になれば幸いです。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。