Railsでタスク管理アプリを作成_8  

# タスク管理アプリを作ってみよう(続き)

## 1. 前置き

### 1. 前提・事前作業

 * [こっちの投稿](http://qiita.com/fujimohige/items/eff10ae60de651299c05)
 * 例によって[ドットインストール](http://dotinstall.com/lessons/basic_rails_v2/24901)の写経
 * [#25 check_box_tagを使おう](http://dotinstall.com/lessons/basic_rails_v2/24919)から実施



## 2. check_box_tagを使おう

* チェックボックスをつけて進捗を管理する
* `/home/vagrant/taskApp/app/views/projects` の `show.html.erb` を弄る。
* jqueryのajax機能を使って処理を行う
* チェックボックスがクリックされた際に、ajaxでPOSTする処理を行う
* クリックするたびに値がtrue、falseで切り替わる toggleという処理を追加する
* 下記、 __`data-project_id` とか `data-id` と書かないとダメなので注意(projdct_idのデータ、とかidのデータ、的な意味で)__
 * [参考](https://w3g.jp/blog/studies/jquery-data-attr-cache)


```erb:ERB(show.html.erb)

<h1><%= @project.title %></h1>

<ul>
    <!-- projectに紐付くtaskがあるだけループする -->
    <% @project.tasks.each do |task| %>
    <li>
        <!-- 進捗管理用チェックボックス -->
        <!-- idやvalueは不要なのでオプションはブランク -->
        <!-- task.done がチェックの有無を意味する(true, false) -->
        <!-- taskのIDとprojectのIDを属性として保持させて使えるようにする -->
        <%= check_box_tag '', '', task.done, {'data-id' => task.id, 'data-project_id' => task.project_id} %>
        <!-- taskのtitleを表示 -->
        <%= task.title %>
        <!-- 削除リンク(taskのプロジェクトIDとtaskIDを取得) -->
        <%= link_to "[Delete]", project_task_path(task.project_id, task.id), method: :delete, data: {confirm: "are you sure?"} %>
    </li>
    <% end %>

    <!-- 新規タスク登録フォーム -->
    <li>
        <%= form_for [@project, @project.tasks.build] do |f| %>
        <%= f.text_field :title %>
        <%= f.submit %>
        <% end %>
    </li>

</ul>

<!-- jqueryの機能を使ってチェックボックスの制御を行う -->
<script type="text/javascript">
    $(function() {
        $("input[type=checkbox]").click(function() {
            $.post('/projects/'+$(this).data('project_id')+'/tasks/'+$(this).data('id')+'/toggle')
        })
    })
</script>

```

* チェックボックスが追加された。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/f5305b09-48a1-2973-a470-6a953cf4efc2.png)

* ソースを見てみると...

```html:HTML
    <!-- projectに紐付くtaskがあるだけループする -->
    <li>
        <!-- 進捗管理用チェックボックス -->
        <!-- idやvalueは不要なのでオプションはブランク -->
        <!-- task.done がチェックの有無を意味する(true, false) -->
        <!-- taskのIDとprojectのIDを属性として保持させて使えるようにする -->
        <input data-id="4" data-project_id="4" id="" name="" type="checkbox" value="" />
        <!-- taskのtitleを表示 -->
        task1
        <!-- 削除リンク(taskのプロジェクトIDとtaskIDを取得) -->
        <a data-confirm="are you sure?" data-method="delete" href="/projects/4/tasks/4" rel="nofollow">[Delete]</a>
    </li>
```

* 確かに属性が追加されている

* `/projects/project_id/tasks/task_id/toggle` というルーティングが定義されていないので、定義しておく
 * 特定の命令を特定のActionに紐付ける設定の追加

* `/home/vagrant/taskApp/config` の `routes.rb` を弄る

```rb:ruby(routes.rb)

  post 'projects/:project_id/tasks/:id/toggle' => 'task#toggle'

```

* `rake routes` でルーティングは更新しておく
* 下記ルーティングが追加されている

```
POST   /projects/:project_id/tasks/:id/toggle(.:format) task#toggle
```

* さらに `/home/vagrant/taskApp/app/controllers` の `tasks_controller.rb` を弄る

```rb:ruby(tasks_controller.rb)

class TasksController < ApplicationController


  # createアクションを追加
  def create
    # 画面からわたってきたIDからprojectをfindする
    @project = Project.find(params[:project_id])
    # taskを登録
    @task    = @project.tasks.create(tasks_params)
    # 遷移先はプロジェクト詳細画面
    redirect_to project_path(@project.id)
  end
  # destroyアクションを追加
  def destroy
      @task = Task.find(params[:id])
      @task.destroy
      redirect_to project_path(params[:project_id])
  end
  # toggleアクションを追加
  def toggle
      render nothing: true
      @task      = Task.find(params[:id])
      # タスクのdoneの値をひっくり返す
      @task.done = !@task.done
      @task.save
      # 下記でもいいけど、render nothing: true でOKなので、下記はコメントアウト
      # redirect_to project_path(params[:project_id])
  end

  private
    # task_params を定義
    def tasks_params
      # taskでわたってきたもののうち、titleだけ使用
      params[:task].permit(:title)
    end

end


```

* 動作確認してみる。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/00f95906-ef1a-ead0-bd2b-13d27c2d8bba.png)

* 404が返ってる
* エラーが出てる`http://dev.com:3000/projects/5/tasks/3/toggle` を直接開いてみる

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/40160/df34b7df-9546-9517-afd2-49d0d733e8d7.png)

* ルーティングがダメらしい。どれどれ...

```rb:ruby(routes.rb)

  post 'projects/:project_id/tasks/:id/toggle' => 'task#toggle'

```

*頭に `/` が抜けてる。さらに、 `task#toggle` じゃなくて `tasks#toggle` が正しい。追加して再度実行

* エラーは無くなった。(キャプチャ割愛)