ActiveStorageを使って複数画像管理をしてみる

ActiveStorageについて仕事で利用するかも、となったので、少し調べてみた。
その時の情報を簡単にまとめる。

###環境
Mac　High Sierra
ruby 2.5.1
Rails 5.2.2

#実装したこと
複数画像をアップして表示する際の手順を記載してみる。
・index画面に画像一覧を表示させる
・new画面を用意する
**バリデーションやエラーチェックなどはあまり気にせず作成**
**最低限の機能ってことで、一覧、新規追加、削除しか搭載しない**

#1.rails new
rails newする

```ruby
rails new as_sample
```

記事作成時はsqlite3でエラーが出た

```bash
Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? can't activate sqlite3 (~> 1.3.6), already activated sqlite3-1.4.0. Make sure all dependencies are added to Gemfile.
```

ので、Gemfileの編集をする

```Gemfile:Gemfile
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.3.6'
```

#2.active_storageインストール、マイグレーション

```bash
cd as_sample
rails active_storage:install
rails db:migrate
```

[マイグレーション結果]
active_storage_blobs,active_storage_attachmentsテーブルが作られる

```
== 20190301155320 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs)
   -> 0.0027s
-- create_table(:active_storage_attachments)
   -> 0.0124s
== 20190301155320 CreateActiveStorageTables: migrated (0.0153s) ===============
```

#3.モデル作成、画像関連づけ

```bash
rails g model item name:string
rake db:migrate
```

```ruby:app/models/item.rb
class Item < ApplicationRecord
  has_many_attached :images
end
```

#4.コントローラー作成

```bash
rails g controller items
```

#5.ルーティング設定

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :items
end
```

#6.コントローラー設定

```ruby:app/controller/items_controller.rb
class ItemsController < ApplicationController

  # item一覧
  def index
    @items = Item.all
  end

  # item新規作成
  def new
    @item = Item.new
  end

  # item作成
  def create
    @item = Item.new(item_params)

    if @item.save
      redirect_to items_path
    else
      render :new
    end
  end

  # item削除
  def destroy
    @item = Item.find(params[:id])
    @item.destroy
    redirect_to items_path
  end

  private

  def item_params
    params.require(:item).permit(:name, images: [])
  end
end

```

#7.ビューの設定
一覧と新規作成画面を用意する。

### 一覧画面
```html:app/views/items/index.html.erb
<h1>Items Index</h1>
<%= link_to 'Add item', new_item_path %>

<ul>
  <% @items.each do |item| %>
    <li>
      <p><%= item.name %></p>
      <%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' } %>
      <% item.images.each do |image| %>
        <%= image_tag(image, width:100) %>
      <% end %>
    </li>
  <% end %>
</ul>
```
画像のサイズは一旦width:100で設定


### 新規作成画面
```html:app/views/items/new.html.erb
<h1>Add Item</h1>

<%= form_with model: @item do |form| %>
  <div>
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>

  <div>
    <%= form.label :images %>
    <%= form.file_field :images, multiple: true %>
  </div>

  <div>
    <%= form.submit %>
  </div>
<% end %>
```

#8.ローカルサーバー起動

```bash
rails s
```

###8-1. http://localhost:3000/items  にアクセス
<img width="350" alt="スクリーンショット 2019-03-02 1.26.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/248644/60a1d2da-dbaa-7468-62e3-b1114cf594ec.png">



###8-2.item新規作成で画像を選択
ファイル選択から画像ファイル2つを選択した状態
<img width="350" alt="スクリーンショット 2019-03-02 1.29.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/248644/66dd1ba6-719e-3562-88e2-baab9fea2b65.png">

###8-3.Create_itemして一覧に遷移した後
<img width="350" alt="スクリーンショット 2019-03-02 1.29.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/248644/a3d2a061-a9ba-a958-d041-b6cad4aa1aaf.png">


とりあえず、想定した動作を作ることができた。

#images: []に入るパラメータ
viewで選択したimagesはcontroller側にどんな値で渡されているかを確認してみる。
個人的に見やすくするために改行する。

```bash
# ActionDispatch::Http::UploadedFile クラスのインスタンス

"images"=>
[
#<ActionDispatch::Http::UploadedFile:0x00007fa524251a18 
@tempfile=#<Tempfile:/var/folders/nf/0ssmnnv545d65f2xd8fcmz2cnr376k/T/RackMultipart2019xxxx-51778-hpwm2k.jpg>,
@original_filename="hogehoge.jpg", 
@content_type="image/jpeg", 
@headers="Content-Disposition: form-data; name=\"image[images][]\"; filename=\"hogehoge.jpg\"\r\nContent-Type: image/jpeg\r\n">
, 
#<ActionDispatch::Http::UploadedFile:0x00007fa5242519c8 @tempfile=#<Tempfile:/var/folders/nf/0ssmnnv545d65f2xd8fcmz2cnr376k/T/RackMultipart2019xxxx-51778-6nsna7.jpg>,
@original_filename="fugafuga.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"image[images][]\"; filename=\"fugafuga.jpg\"\r\nContent-Type: image/jpeg\r\n">
]
```
それぞれの情報は以下のようになる

@tempfile : 画像データ情報(パス情報？)
@content_type: 画像の形式 (jpg,pngとか)
@original_filename : ファイル名情報 
@headers: ヘッダーに関する情報 (データ形式など)

簡単な動きと渡されるパラメータについて少し知れたので、
次はVueを使って画像登録処理を実装してみようと思う。