【Rails入門】Ajaxを導入する2

前回（[【Rails入門】Ajaxを導入する](https://qiita.com/puripuri_corgy/private/b185945a4dfa560cae1d)）よりも、実践的な内容になっています。

#ajaxを使った入力フォームを実装する方法

##0. どんなものを実装するのか、確認する

・初期画面
<img width="954" alt="スクリーンショット 2019-09-16 22.09.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/083fb2d3-bdb1-155b-2696-248fd97a7ca6.png">

・ボタンを押すとポスト用のフォームが現れる。
・値を入力し、送信すると動的にデータが更新される。
・ポスト用のフォームは消える。

##1. Modelを作成する
まず、データを保存するためにModelを作成しておく。

```
$ rails g model Apple name:string
$ rake db:migrate
```
モデルを作成し、マイグレーションファイルを実行。

nameのカラムを持ったAppleモデルを作成できました。

##2. Controllerを作成する

```
$ rails g controller apples
```

##3. Routeを追加する

```:app/config/routes
resources :apples
```
リソースを振り分けるので、上記のコードを追加する。
これでRESTfulなリソースの振り分けができる。

* RESTfulなリソースの振り分けについてのヒント：[【Rails入門】初めてのWebアプリ開発ならscaffoldが最短！](https://www.sejuku.net/blog/26515#scaffoldWebRESTful)


##4. まずはControllerから作成する
以下のコードを追加する。

```ruby:app/controller/apples_controller.rb
class ApplesController < ApplicationController
 
  def index
    @apples = Apple.all
  end
 
  def new
    @apples = Apple.new
    # respond_toメソッド => 結果をどのフォーマットで返すかを指定している
    respond_to do |format|
      # turbolinkが有効でないとき
      format.html
      # turbolinkが有効なとき
      format.js
    end
  end
 
  def create
    @apples = Apple.all
    @apple = Apple.new(apple_params)
    # respond_toメソッド => 結果をどのフォーマットで返すかを指定している
    respond_to do |format|
      if @apple.save
        # turbolinkが有効でないとき
        format.html
        # turbolinkが有効なとき
        format.js
      else
        # turbolinkが有効なとき
        format.js {render :new}
      end
    end
  end
 
  def apple_params
    params.require(:apple).permit(:name)
  end
end
```

##4. Viewを作成する

```erb:app/views/apples/index.html.erb
<h1>Appleモデル一覧</h1>
<table class="table" id="apples">
  <!-- パーシャル -->
  <%= render @apples %>
</table>
<!-- :remote => trueの部分で、turbolinkを有効にする -->
<!--  => 自動的にajaxの処理にする -->
<!-- "データを追加する”のボタンを押すと、applesのnewアクションが実行される -->
<%= link_to "データを追加する", new_apple_path, remote: true %>
<div id="apple-form"></div>
```
`<%= render @apples %>`の部分でパーシャルを入れているので、該当するパーシャルを作成する必要があります。

##5. Viewで、該当するパーシャルを作成する

`app/views/apples/_apple.html.erb`を作成する。
(`@apples`のように書くと、自動的に_apple.html.erbを検索します。)

```erb:app/views/apples/_apple.html.erb
<tr>
  <td>
    <%= apple.name %>
  </td>
</tr>
```
=> これで、コントローラーで設定した変数から値を出力できる。

```ruby:indexアクションの内容
def index
  @apples = Apple.all
end
```

=> "データを追加する”のボタンを押すと、applesのnewアクションが実行される。

```ruby:newアクションの内容
def new
  @apples = Apple.new
  respond_to do |format|
    format.html
    format.js
  end
end
```
ajaxで実行しているので、format.jsに該当するnew.js.erbを返す。

##6. Viewで、該当するパーシャルを作成する2

```erb:app/views/apples/new.js.erb
<script>
  // renderでformを指定している => _form.html.erbを作成して入力フォーム用のコードを入力する必要がある
  $('#apple-form').html("<%= j (render 'form') %>");
  $('#apple-form').fadeIn(800);
</script>
```

##7. Viewで、該当するパーシャルを作成する3

```erb:app/views/apples/_form.html.erb
<%= simple_form_for @apples, remote: true do |f| %>
  <%= f.input :name %>
  <%= f.button :submit ,"追加" %>
<% end %>
```
ここでは、`simpel_form`というformを簡素化してくれるgemを使用している。なので、

```
gem 'simple_form'
```

を追加したあと、

```
$ bundle install
```

をして、Gemを有効にする。

また、simple_formの初期設定のためにコマンドプロンプトに以下のコードを入力する。

```
$ rails generate simple_form:install
```

これで、simple_formが使用可能になる。


1〜7で、`・ボタンを押すとポスト用のフォームが現れる。`まで完了した。

残りは、
・値を入力し、送信すると動的にデータが更新される。
・ポスト用のフォームは消える。　　です。


この後はフォームに値を入力してポストした後の動作を実装する。

値がポストされるとコントローラーで設定したcreateアクションが呼び出される。

```ruby:createアクションの内容
def create
  @apples = Apple.all
  @apple = Apple.new(apple_params)
  respond_to do |format|
    if @apple.save
      format.html
      format.js
    else
      format.js {render :new}
    end
  end
end
```

値を受け取って、saveに成功すればformat.jsに該当するcreate.js.erbが実行される。
app/views/apples/create.js.erbを作成して以下のコードを作成する。


##8. Viewで、該当するパーシャルを作成する4

```erb:app/views/apples/create.js.erb
<script>
$('#apples').html("<%= j (render 'index') %>");
$('#apple-form').fadeOut(600);
</script>
```

render ‘index’の部分でindexのパーシャルを出力し、またfadeOutでフォームを見えないようにしている。

では、パーシャルの内容を入力していく。

##9. Viewで、該当するパーシャルを作成する5
app/views/apples/_index.html.erbを作成して以下のコードを入力してください。

```ruby:app/views/apples/_index.html.erb
<%= render @apples %>
```

これで、自動的に_apple.html.erbにアクセスして値を更新する。


##10. まとめ
これで、ajaxの設定が完了した。作成したviewは

・_apple.html.erb
・_form.html.erb
・_index.html.erb
・create.js.erb
・index.htlm.erb
・new.js.erb

の6つです。

`http://localhost:3000/apples` を開いて確認しましょう！