【Rails】Ajax通信でできること2（ページの一部だけを更新する編）

どうもこんにちは。

今回も、RailsでのAjax通信について紹介をしようと思います。

Ajax通信とはなんぞやということは前回の記事に記載していますので、ぜひこちらもご参照ください。

https://qiita.com/PDC-Kurashinak/private/313b0344b97cbd0a4aa4

今回は、「パーシャルを使用してページの一部を更新する」ということをやっていこうと思います。

#  早速実装

「パーシャルを使用してページの一部を更新する」という動作を実現するためには以下のようなの順序で行います。

1. モーダルでフォームにデータを入力する
1. モーダルで登録ボタンを押す
1. 登録ボタンを押されたことをトリガーにjavascriptのクリックイベントが動作する
1. javascript側で入力された情報を取得する
1. javascript側からAjax通信によってcreate_ajaxメソッドが動作する
1. create_ajaxメソッドで登録処理が行われる
1. 登録処理が終わったらページを更新するためにパーシャルの内容を動的に書き換える
1. 更新したパーシャルを表示する

## html.erb
今回はモーダルの中の表の中身を動的に変えるコードを示していきます。
`id="display_title"`のところにパーシャルを入れ込みます。

```erb
<div id="sample_ajax_modal" class="modal fade show" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-modal="true" data-toggle="modal">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">タイトル追加</h4>
                <button type="button" class="closeModal close" data-dismiss="modal" aria-hidden="true">×</button>
            </div>
            <div class="modal-body p-4">
                <div class="row">
                    <div class="col-md-12">
                        <div class="form-group row">
                            <div class="col-sm-2">
                                <label class="control-label">タイトル</label>
                            </div>
                            <div class="col-sm-10">
                                <%= text_field_tag 'sample_ajax_title', "", class: 'form-control' %>
                            </div>
                        </div>
                    </div>
                </div>
                <button type="button" id="create_title" class="btn btn-success waves-effect waves-light pull-right ml-2 mt-2">追加</button>
                <button type="button" class="closeModal btn btn-light waves-effect waves-light pull-right ml-2 mt-2">キャンセル</button>
                <div class="row">
                    <div id="display_title" >
                </div>
            </div>
        </div>
    </div>
</div>
```

## javascript

javascriptのファイル名は、モデル名.jsにしておきましょう。パスの設定も忘れずに。

```javascript
document.addEventListener('DOMContentLoaded', function() {
    // ボタンを押された時のクリックイベント
    document.getElementById('create_title').addEventListener('click', function() {
        // テキストフィールドからタイトルを取得します
        var title = document.getElementById('sample_ajax_title').value;

        // Ajax通信を開始します
        fetch('/sample_ajax/create_change_ajax', {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                // RailsのCSRFトークンを設定します
                'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
            },
            body: JSON.stringify({ title: title })
        })
        .then(response => response.json())
        .then(data => {
            console.log(data);
        })
        .catch(error => {
            console.error('Error:', error);
        });
    });
});

```

## controller

`format.js { render 'sample_ajaxs/display_title' }`というようにレスポンドフォーマットを`js`に指定することで、Viewのディレクトリから`sample_ajaxs/display_title.js.erb`ファイルを探します。

ルーティングの設定を`GET`として`config/routes.rb`に記述をしておきましょう。

```ruby
def create_change_ajax
    sample_ajax = SampleAjax.new(title: params[:title])
    respond_to do |format|
        if sample_ajax.save
            @sample_ajaxs = SampleAjax.all
            format.js { render 'sample_ajaxs/display_title' }
            format.json { render json: 'save ok' }
        else
            @sample_ajaxs = SampleAjax.all
            format.js { render 'sample_ajaxs/display_title' }
            format.json { render json: 'save fail' }
        end
    end
end
```

## view（display_title.js.erb）

コントローラでこのファイルが呼ばれます。
以下のコードの意味は、「IDが`display_title`の要素に`display_table_partial`というパーシャルをhtml形式で入れ込みます。」です。

```erb
$("#display_title").html("<%= j render 'display_table_partial' %>");
```

## view（_display_table_partial.html.erb）

`display_title.js.erb`で呼ばれるパーシャルです。

```erb
<table>
    <thead>
        <tr>
            <th>タイトル</th>
            <th>作成日時</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><%= @sample_ajaxs.title %></td>
            <td><%= @sample_ajaxs.created_at %></td>
        </tr>
    </tbody>
</table>
```

上記の実装によってボタンがクリックされた時に登録処理が実行され、ページを更新しなくても表の内容を変えることができるようになります。

# まとめ

今回もAjax通信についてまとめてみました。

前回と同様にJavascriptを使用したことに加えて、`js.erb`ファイルを使用することで、画面表示を非同期で行うことができるようになります。

Javascriptファイルからもhtmlを呼び出すことはできますが、コントローラからJavascriptへレコードの入った変数を渡すことはできないので、titleの入った配列、作成日時の入った配列を作らなきゃいけません。さらにJavascriptで配列を展開してhtmlに落とし込む。これが非常にめんどくさい。

↓Javascriptファイルからもhtmlを呼び出す時のコントローラのコード↓

```ruby
respond_to do |format|
    if sample_ajax.save
        @sample_ajaxs = SampleAjax.all
        sample_ajaxs_array = @sample_ajaxs.pluck(:title, :created_at)
        format.json { render json: sample_ajaxs_array }
    else
        @sample_ajaxs = SampleAjax.all
        sample_ajaxs_array = @sample_ajaxs.pluck(:title, :created_at)
        format.json { render json: sample_ajaxs_array }
    end
end
```

なので、こういう場合は今回のようにjs.erbファイルを有効的に活用していくことをおすすめします。

以上