rails javascript/jqueryの実装　実践編


実際に実装方法を書いて行きます。

# コントローラー(respond_to)
  Railsのコントローラーで利用できる respond_to というメソッドは
  「リクエストがHTMLそれともJSONのレスポンス求めているのか」を条件に条件分岐してくれます。

　HTMLを返す場合は、該当するビューを呼びその中でデータを生成していましたが
　JSONを返す場合はRubyのハッシュをrenderメソッドの引数として渡すだけでJSONに変換されます。

```ruby:controller
respond_to do |format|
  format.html { render ... } # この中はHTMLリクエストの場合に呼ばれる
  format.json { render ... } # この中はJSONリクエストの場合に呼ばれる
end

# 例
respond_to do |format|
  @comment = Comment.create(comment_params)
  format.html { redirect_to :root }
  format.json { 
    render json: { id: @user.id, comment: @comment }
  }
end

=begin
 renderというメソッドに{json: { id: @user.id, comment: @comment }}
 というハッシュを引数として渡しています。
=end
```

# JavaScriptを記載
rails内では
JavaScriptファイルをassets/javascripts以下に作成します。
.js拡張子で作成します。

# jQueryを読み込み
Ruby on Railsでは、アプリケーション作成時にjquery-railsというgemをインストールし、
assetsディレクトリ以下のapplicaton.jsファイルで

```js:applicaton.js
//= require jquery
```
このように記述することでjQueryを読み込んでいます。

# javascript/jqueryのコード

## $.ajax

```js:.js
$.ajax({
      type: 'get',
      url: '/comment.json',
      data: {
        comment: {
          content: comment
        }
      },
      dataType: 'json'
    })
```

少し複雑なのは、オブジェクト型の入れ子になっているdata以降の記述です。
dataというキーに対してのバリューはオブジェクト型であり
さらにそのバリューもオブジェクト型になるという、入れ子構造となっています。

それぞれの意味はこちら

| オプション | 説明 |
|:-:|:-:|
| type | HTTP通信の種類を記述する。通信方法は、GETとPOSTの2種類がある。 |
| url | リクエストを送信する先のURLを記述する。 |
| data | サーバに送信する値を記述する。 |
| dataType | サーバから返されるデータの型を指定する。 |

## doneとfail
ajaxメソッドの後につけることで、非同期通信が成功した際/失敗した際に行う処理を書くことができます。
両方とも、ajaxメソッドとセットとなるメソッドです。

doneは通信が成功したときに、failは通信が失敗したときに動きます。

```js:.js
    .done(function(data) {
      var html = $('<li class="comment">').append(comment.content);
      $('.comments').append(html);
      textField.val('');
    })
    .fail(function() {
      alert('error');
    });
```

### .doneのあとにあるdataという変数について
doneのうしろにあるdataという変数には
リクエストによって返ってきたレスポンスが代入されます。
この場合のレスポンスは、非同期通信によって作成したCommentにあたります。

```ruby:controller
def create
  @comment = Comment.create(comment_params)
  respond_to do |format|
    format.html { redirect_to :root }
    format.json { render json: @comment} #ここの記述からdeta変数に返されます。
  end
end
```

## htmlを生成する記述

```js:.js
$(function() {
  function buildHTML(comment) {
    var html = $('<li class="comment">').append(comment.content); //var htmlを受け取る
    return html;   //htmlで返す
  }
  //ここまでの記述でvar htmlを受け取り実行

    //省略
    $.ajax({
    //省略
    .done(function(data) {
      var html = buildHTML(data); //成功した場合data変数を受け取る
    //省略
    })
    .fail(function() {
      alert('error');
    });
  });
});
```

# 総まとめ

jsファイルのまとめコードです。

```js:.js
$(function() {
  function buildHTML(comment) {
    var html = $('<li class="comment">').append(comment.content);
    return html;
  }

  $('.js-form').on('submit', function(e) {
    e.preventDefault();
    var textField = $('.js-form__text-field');
    var comment = textField.val();
    $.ajax({
      type: 'POST',
      url: '/comments.json',
      data: {
        comment: {
          content: comment
        }
      },
      dataType: 'json'
    })
    .done(function(data) {
      var html = buildHTML(data);
      $('.comments').append(html);
      textField.val('');
    })
    .fail(function() {
      alert('error');
    });
  });
});
```