今回はrefileで画像を複数投稿できる機能を作ります。
調べたところ、画像複数投稿には gem 'carrierwave'を使用する記事がたくさん出てきましたが、うまくいかなかったので今回はrefileで実装してみました。
##画像投稿用のテーブルを作成
画像1枚だけの投稿だと、対象のモデルにimageカラムを追加するだけでいいのですが、複数枚となると別でテーブルを作成する必要があります。
私はpet_imageモデルを新規作成しました。
create_table "pet_images", force: :cascade do |t|
t.integer "pet_id"
t.string "image_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["pet_id"], name: "index_pet_images_on_pet_id"
end
##リレーションを組む
1:Nの関係性を持たせます。
pet.rb
has_many :pet_images, dependent: :destroy
accepts_attachments_for :pet_images, attachment: :image
pet_image.rb
belongs_to :pet
attachment :image
##コントローラーを編集
pet.controller.rb
private
def pet_params
params.require(:pet).permit(:name, :birthday, :gender, :introduction, :genre_id, :prefecture_id, :age, :is_active, :image, pet_images_images:[] )
end
##新規投稿フォーム編集
pet.new.html
<%= form_with model: @pet, url: pets_path, method: :post, local: true do |f| %>
<%= f.attachment_field :pet_images_images, multiple: true %>
<% end %>
##ペット一覧には画像を一枚だけ表示させたいので以下のように記述
pet.index.html
<% pet.pet_images.first(1).each do |image| %>
<%= attachment_image_tag image, :image, size: '200x200' %>
<% end %>
##画像を複数枚表示させたいところには↓
pet.show.html
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
<div id="slider">
<% @pet.pet_images.each do |image| %>
<%= attachment_image_tag image, :image, size: '350x350', class: "rounded mt-4" %>
<% end %>
</div>
##プラスでスライドショーにする
application.html
<head>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css"/>
</head>
application.js
$(function() {
$('#slider').slick({
dots: true,
autoplay: true,
autoplaySpeed: 4000,
});
});
application.css
.slick-next {
right: 10px
z-index: 100;
}
.slick-prev {
left: 10px
z-index: 100;
}
以上です!!