Ajax通信をrubyに導入した話

#jQueryでAjax通信 × Railsでサーバー処理#

jQueryのコードを使ってAjax通信でリクエストし、その処理をRailsで行ってjson形式のレスポンスで返したいと思います。
具体的には、「ボタンをクリックしたらリクエストが発動して、設定したデータをRailsに送信し、レスポンスをクラインアントが受け取っとら、アラートやコンソール上で送られてきたデータを表示する」ということをやってみたいと思います。

今回は、クライアント側とサーバー側を分かりやすくするため、Erbを使わずに処理を行いたいと思います。
したがって、今回利用するファイルの拡張子は以下になります。

####クライアント側####

- html
- js

####サーバー側####

- rb

##HTMLファイルで必要なコード##

・jQueryのサーバーから、jQueryを使えるようにする機能を読み込むコード（いわゆるjQueryの導入）

```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
```

・JavaScriptファイルを読み込むコード

```
<script src="sample.js"></script>
```

・サーバーへリクエストするボタン

```
<input type="button" id="btn1" value="ボタン">
```

これらを組み合わせたhtmlのソースコードは以下になります。

```sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Ajaxの練習</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="sample.js"></script>
</head>
<body>
  <input type="button" id="btn1" value="ボタン">
</body>
</html>
```

##JavaScriptファイルに必要なコード##
###Ajax通信するコード###
以下のような違いがあるため、今回は$.ajaxを使うことにします。

| $.ajax | 通信の成功時も失敗時の処理も書ける |
|:-------|:----------------------------|
| $.post | 通信の成功時の処理のみしか書けない |

###パラメータ###

・クライアントからのリクエストの送信先を指定

```
url: "/test"
```

・HTTP通信の種類を設定
GETとPOSTがありますが、今回はPOSTで、データを送信します。

```
type: "POST"
```

・サーバーからのレスポンスを受け取るデータ形式を設定。

```
dataType: "json"
```

・サーバーへ送るデータの中身

```
data: { user: { name: "foo", age: 25 } }
```

###メソッド###

・成功時の処理
<details><summary>通信が成功したか分かりやすくするため、アラートでデータを表示されるようにしています。</summary>
GoogleChromeだと、alertだけでは「object」としか表示されないため、
特別なメソッド（JSON.stringify）を追加する必要がある。
</details>

```
done(function(human){
  alert(JSON.stringify(human));
});
```

・失敗時の処理（任意）
<details><summary>通信が失敗したら、送ったデータをコンソール上で表示するようにしています。</summary>responseTextメソッドは、Ajax通信途中のデータを取得できるメソッド。</details>

```
fail(function(human){
  console.log(human.responseText);
});
```

・成功しても失敗しても行われる処理

```
always(function(){
  console.log(human);
});
```

####これらのjQueryのコードをまとめると以下になります。####

<details><summary>補足</summary>
id属性btn1のボタンをクリックしたら、以下のAjax通信を行う（$.ajax）
・/testに、userというデータをPOSTで送る。
・サーバーからのレスポンス時にはJSON形式でデータを受け取る。
・通信成功時には、返ってきたデータ（変数human）をアラートでブラウザに表示する。(.done)
・通信失敗時には、レスポンスされたデータを文字列としてコンソール上に表示する。(.fail)
・通信成功時でも失敗時でも、レスポンスされたデータをコンソール上に表示する。(.always)
</details>


```sample.js
$(function(){
  $('#btn1').click(function(){
    $.ajax({
      url: "/test",
      type: "POST",
      dataType: "json",
      data: { user: { name: "foo", age: 25 } }
    })
    .done((human) => {
      alert(JSON.stringify(human))
    })
    .fail((human) => {
      console.log(human.responseText)
    })
    .always((human) => {
      console.log(human)
    });
  });
});
```

##Rails（サーバー側）で必要なコード##

・ルーティング
jsファイルに記述した、リクエストの送信先（/test）を設定します。

```route.rb
Rails.application.routes.draw do
  get "/test", to: 'statics#test'
  post "/test", to: 'statics#test'
end
```

・コントローラ
<details><summary>jsファイルに記述した、送信するデータを受け取り、json形式でクライアントにレスポンスで返します。</summary>
・送信されたデータ{ user: { name: "foo", age: 25 } }を、変数humanで受け取る
・変数humanをjson形式でレスポンスする。
</details>

```statics_controller.rb
class StaticsController < ApplicationController
  def test
    human = params[:user]
    render :json => human
  end
end
```

##最後に##

うまくいけば以下のような表示になると思います。
<img width="938" alt="スクリーンショット 2020-05-25 16.18.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562793/3edfa961-32d0-8863-27a3-266f8622c99c.png">

いかがだったでしょうか、非同期通信を行うことで身軽な通信ができて、大勢の人に知れ渡るアプリへの一歩になるんじゃないかと思います。

ただその分、初心者には複雑な仕組みになりがちなので、参考にしていただければと思います。