Rails4×Bootstrap3でNew/Edit画面をモーダルダイアログ化する

参考
http://richonrails.com/articles/basic-ajax-in-ruby-on-rails

## Controller

```rb
class ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update, :destroy]

  def index
    @products = Product.all
  end

  def show
  end

  def new
    @product = Product.new
  end

  def edit
  end

  def create
    @product = Product.create(product_params)
    @products = Product.all
  end

  def update
    @product.update(product_params)
    @products = Product.all
  end

  def destroy
    @product.destroy
    redirect_to products_url
  end

  private
    def set_product
      @product = Product.find(params[:id])
    end

    def product_params
      params.require(:product).permit(:name)
    end
end
```

**POINT**

* create、updateでリダイレクトしない
* create、update後は `@products = Product.all` で最新の値を取得

## View
### Index

```erb:index.html.erb
<h1>Listing products</h1>

<table class="table">
  <thead>
    <tr>
      <th>Name</th>
      <th colspan="2"></th>
    </tr>
  </thead>

  <tbody class="product-index">
    <%= render "index" %>
  </tbody>
</table>

<br>

<%= link_to 'New Product', new_product_path, remote: true %>

<div id="product-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"></div>
```

```erb:_index.html.erb
<% @products.each do |product| %>
  <tr>
    <td><%= product.name %></td>
    <td><%= link_to 'Edit', edit_product_path(product), remote: true %></td>
    <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
```

**POINT**

* tbodyは `class` を付けて外出し（パーシャル）
* new/editのリンクに `remote: true` オプションを追加
* 適当な場所に `<div id="product-modal" class="modal fade"〜` を挿入

### Modal用

```erb:_modal.html.erb
<div class="modal-dialog">
  <div class="modal-content">
    <%= form_for(@product, remote: true) do |f| %>
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">New/Editing product</h4>
      </div>
      <div class="modal-body">
        <div class="field">
          <%= f.label :name %><br>
          <%= f.text_field :name %>
        </div>
      </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <%= f.submit "Save", :class => "btn btn-primary" %>
        </div>
      </div>
    <% end %>
  </div>
</div>
```

**POINT**

* form_forに `remote: true` オプションを追加


### New

```erb:new.js.erb
$("#product-modal").html("<%= escape_javascript(render 'new') %>")
$("#product-modal").modal("show")
```

```erb:_new.html.erb
<%= render partial: 'modal' %>
```

### Create

```erb:create.js.erb
<%= render 'save' %>
```

```erb:_save.js.erb
$(".product-index").html("<%= escape_javascript(render 'index') %>")
$("#product-modal").modal("hide")
```

### Edit

```erb:edit.js.erb
$("#product-modal").html("<%= escape_javascript(render 'edit') %>")
$("#product-modal").modal("show")
```

```erb:_edit.html.erb
<%= render partial: 'modal' %>
```

### Update

```erb:update.js.erb
<%= render 'save' %>
```

```erb:_save.js.erb
# Createと共通
```