refileの基本と複数画像のアップロード

Railsで商品画像や写真の投稿を行う際、とっても便利なファイルアップロードのgem 「 ***refile*** 」。
AWSでS3に保存するのも簡単にできるが、なにぶんぐぐっても情報が少なくて苦戦する！
そんなわけで基本的な内容と複数画像についてのご紹介です╭( ・ㅂ・)و
<br>
###  1：ImageMagick インストール
Macの方　`$ brew install ImageMagick`
Vagrantの方　`$ sudo yum install -y ImageMagick ImageMagick-devel`
<br>
###  2：Gem インストール
Gemfileに以下を追記

```
gem "refile", github: 'refile/refile', require: "refile/rails"
gem "refile-mini_magick", github: 'refile/refile-mini_magick'
```

`$ bundle install`
（場合によっては`$ bundle update`が必要）
<br>
###  3：model 設定・記述
今回は複数画像アップロードしたいので、dbはProductモデルとProductImageモデルを１対多にします。
Productモデルのカラムには name(string), price(integer), description(text)
ProductImageモデルには product_id(integer), image_id(string)
注）画像が保存されるimage_idカラムは必ず_idをつける。データ型はstringで！

```ruby:/app/models/product.rb
class Product < ApplicationRecord
  has_many :product_images, dependent: :destroy
  accepts_attachments_for :product_images, attachment: :image
end
```

オプションにdependent: :destroyを入れることで、商品が削除されたら紐づいている商品画像も削除します。

```ruby:/app/models/product_image.rb
class ProductImage < ApplicationRecord
  belongs_to :product
  attachment :image
end
```

###  4：controller 記述

```ruby:/app/controllers/products_controller.rb
class ProductsController < ApplicationController

  def new
    @product = Product.new
    @product.product_images.build
  end

  def create
    @product = Product.new(product_params)
    @product.save
    redirect_to products_path
  end

  def edit
    @product = Product.find_by(id: params[:id])
  end

  def show
    @product = Product.find_by(id: params[:id])
  end

( 一部省略 )

  private

  def product_params
    params.require(:product).permit(:name, :price, :description, product_images_images: [])
  end
end

```

注）ProductImageは複数画像アップの際は配列[]で渡さなくてはいけない。
<br>
###  5：View 記述

```ruby:/app/views/products/new.html.erb
<h1>販売商品新規追加</h1>
<%= render partial: "shared/product_form", locals: { product: @product } %>
```

```ruby:/app/views/products/edit.html.erb
<h1>販売商品編集</h1>
<%= render partial: "shared/product_form", locals: { product: @product } %>
```

```ruby:/app/views/shared/_product_form.html.erb
<%= form_for(product) do |f| %>
  <p>商品名：<%= f.text_field :name %></p>
  <p>価格：¥<%= f.text_field :price %></p>
  <p>商品説明文：<%= f.text_field :description %></p>
  <p>商品画像：<%= f.attachment_field :product_images_images, multiple: true %></p>
  <%= f.submit %>
<% end %>
```

注）商品画像のformにはmultiple: true を入れないと複数画像選択できません。
<br>

```ruby:/app/views/products/show.html.erb
<h1><%= @product.name %></h1>

商品名：<%= @product.name %><br>
価格：<%= @product.price %><br>
商品説明文：<%= @product.description %><br>

<% if @product.product_images.present? %>
  <% @product.product_images.each do |image| %>
    <%= attachment_image_tag image, :image, :fill, 200, 200 %>
  <% end %>
  <% else %>
    <%= image_tag 'no_image.jpg', size: '200x200' %>
<% end %>

<%= link_to("編集",edit_product_path(@product.id)) %>
<%= link_to "削除","products/#{@product.id}", method: :delete, data: { confirm: "削除してよろしいですか？" } %>
```

注）商品画像の登録がない場合はno_image.jpgの画像を表示させるために、app/assets/images/no_image.jpgで格納しておく必要があります。
<br>
***
あくまでコードは参考ですが、キモはストロングパラメータを配列で渡す！
これでrefileで複数画像のアップロードができますヾ(●´▽｀●)ﾉ彡☆
refileをさわったのは少し前なので漏れがあるかもしれません！
うまくいかなければコメントください！(汗)
<br>