RailsでAjax基本形（Scaffoldで学ぶ）

## 前提

- 超単純なモデル構造（1モデル）
- コントローラーはindex以外Ajax（シングルページな感じ）
- new, editなんかも新しいページに遷移するんじゃなくて、同じページ内にdivを挿入する感じ
- rails new済のところからスタート
- viewのhtmlレンダリングエンジンはhaml

## 前準備（Ajaxの前まで）

### Model作成

```
$ ./bin/rails g model task name:string
```

### Controller作成

```
$ ./bin/rails g controller tasks
```

### RouteとControlle#index

ベースになるページを作る。

#### ルーティング設定

```config/route.rb
Rails.application.routes.draw do
  root 'tasks#index'
  resources :tasks
end
```

#### コントローラー

```app/controllers/tasks_controller.rb
def index
  @tasks = Task.all
end
```

#### ビュー（ベースになるページ）

```app/views/tasks/index.html.haml
%h1 Task List
  %table{id: "tasks", class: "table"}
    = render @tasks
```

##### 補足

初心者的にようわからんポイントは、 ```= render @tasks``` のとこ・・
これは省略されているだけで、フルで書くと

```= render :partial => 'task', :collection => @tasks ```

になる。

参考：[Rails Best Practices - Simplify render in views](http://rails-bestpractices.com/posts/2010/12/04/simplify-render-in-views/)


#### ビュー（partial）

各taskをリスト表示する部分

```app/views/tasks/_task.html.haml
%tr
  %td=task.name
```

## やっとこさAjaxしますよ！（こっから本題）

### Step 1. 一覧ページに、TaskController#newのajax呼び出しをいれる

さっきのページに一番下に1行追加
ajaxなので ``` remote: true ``` 

```app/views/tasks/index.html.haml
%h1 Task List
  %table{id: "tasks", class: "table"}
    = render @tasks
= link_to "New Task", new_task_path, remote: true
```

### Step 2. Controllerの動き

```app/controllers/tasks_controller.rb
def new
  @tasks = Task.new
  respond_to do |format|
    format.html
    format.js
  end
end
```

scaffoldに従うと、こんな感じで、 ``` respond_to ``` が入ってくる。
コレがないと対応したformatの呼び出しに応答してくれない。。
（htmlはデフォルトなのでなければhtml応答になる）

ここではrenderを省略しているので、Railsのデフォルトであるコントローラーアクション名と同名のテンプレートをレンダーしようとしてくれる。

### remote: true なしの場合

HTMLを返そうとするので、探しに行くテンプレートは
``` app/views/tasks/new.html.haml ```

### remote: true ありの場合

JSを探しに行く
``` app/views/tasks/new.js.erb ```

```app/views/tasks/new.js.erb
$('#task-form').html("<%= j (render 'form') %>");
$('#task-form').slideDown(350);
```

JSコードとして返され、評価される。
erbを使ってフォームのレンダリングを組み込んでいる。
ちなみにerbはRailsのデフォルトなのでhamlを使っていても使えないわけじゃない。
jsコード内にhamlは書きにくいらしいので、erbでやるほうがやりやすいらしい。

jsからレンダーされるform

```app/views/tasks/_form.html.haml
= simple_form_for @task, remote: true do |f|
  = f.input :description
  = f.input :deadline
  = f.button :submit
```

ここでも ``` remote: true ``` が使われているが、これはsubmitのアクションをajax呼び出ししたいから。
ここでは新規作成後のPOSTなので、呼び出されるコントローラーは ```TasksController#create```

```app/controllers/tasks_controller.rb
def create
  @task = Task.build(task_params)
  respond_to do |format|
    if @task.save
      format.html
      format.js
    else
      format.js { render :new }
    end
  end
end
```

呼び出されるのは format.js で指定されている ``` app/views/tasks/create.js.erb ```

``` app/views/tasks/create.js.erb
$('#tasks').html("<%= j (render @tasks) %>");
$('#task-form').slideUp(350);
```

``` j (render @tasks) ``` の j は ```ActionView::Helpers::JavaScriptHelper#escape_javascript```
のエイリアスメソッド。

> Escapes carriage returns and single and double quotes for JavaScript segments.

改行コード、シングルクオート、ダブルクオートをJavaScript用にエスケープしてくれるヘルパメソッド（のエイリアス）

erb が Ruby コードとして解釈した文字列をJavaScriptで正しく扱えるようにエスケープしてくれる。

この例の場合 ``` render @tasks ``` なので、 ``` app/views/tasks/_index.html.haml ``` が評価された文字列が入ってくる。

（RubyMineがあると、```j``` メソッドの呼び出しが何なのか、``` Cmd + B ``` で定義元にジャンプしてくれてとてもわかりやすい）

- - -
## 参考URL

- [The Detailed Guide on How Ajax Works with Ruby on Rails](http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails)

めっちゃわかりやすいので、↑を見れば良い・・という・・・