タスク管理アプリを作ってみよう(続き)
1. 前置き
1. 前提・事前作業
- こっちの投稿
- 例によってドットインストールの写経
- #25 check_box_tagを使おうから実施
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のデータ、的な意味で) - 参考
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>
- チェックボックスが追加された。
- ソースを見てみると...
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
を弄る
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
を弄る
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
- 動作確認してみる。
- 404が返ってる
- エラーが出てる
http://dev.com:3000/projects/5/tasks/3/toggle
を直接開いてみる
- ルーティングがダメらしい。どれどれ...
ruby(routes.rb)
post 'projects/:project_id/tasks/:id/toggle' => 'task#toggle'
*頭に /
が抜けてる。さらに、 task#toggle
じゃなくて tasks#toggle
が正しい。追加して再度実行
- エラーは無くなった。(キャプチャ割愛)