今回は、Taskテーブルにdone:boolean
を加えて、todoリスト・doneリストに分ける
※次回予告は確定ではありません。
Taskテーブルにdoneカラムを追加
% rails g migration add_done_to_tasks done:boolean
そして、
デフォルトfalse
nullもfalse
を追加します
[ Migrationファイル ]
class AddDoneToTasks < ActiveRecord::Migration[6.0] def change add_column :tasks, :done, :boolean, default: false, null: false end end
% rails db:migrate
Seedを変更
今のサンプルデータには、doneカラムの指定がないのでチョコっといじります。
[ db/seeds.rb ]
(省略) users = User.all # todoタスク 15.times do title = Faker::Beer.brand description = Faker::Movies::BackToTheFuture.quote users.each { |user| user.tasks.create!(title: title, description: description) } end # doneタスク 15.times do title = Faker::Beer.brand description = Faker::Movies::BackToTheFuture.quote users.each { |user| user.tasks.create!(title: title, description: description, done: true) } end
doneカラムはdefault: true
としました。
なので、todoタスク用のサンプルデータは特に変更しません。
doneタスク用のサンプルデータの方にだけdone: true
を指定しておきます。
Routingの編集
/tasks/index
でタスク一覧を表示しているが、
/tasks/todo
-> todo一覧/tasks/done
-> done一覧
となるようにしたい!!
そこで、resourecesメソッドのcollectionを使います。
[ config/routes.rb ]
resources :tasks do collection do get :todo, :done end end
collectionの他にmemberもありますが、今回は一覧ページを作りたいのでcollectionを使いました。
resourecesメソッドについて詳しくは↓
https://pikawaka.com/rails/resources#member%E3%81%A8collection
collectionにより、todoアクション
とdoneアクション
が追加されます。
% rails routes | grep task todo_tasks GET /tasks/todo(.:format) tasks#todo done_tasks GET /tasks/done(.:format) tasks#done tasks GET /tasks(.:format) tasks#index POST /tasks(.:format) tasks#create new_task GET /tasks/new(.:format) tasks#new edit_task GET /tasks/:id/edit(.:format) tasks#edit task GET /tasks/:id(.:format) tasks#show PATCH /tasks/:id(.:format) tasks#update PUT /tasks/:id(.:format) tasks#update DELETE /tasks/:id(.:format) tasks#destroy
こんな感じ〜
Controllerの編集
todoアクションとdoneアクションを実装していきます。
[ tasks_controller.rb ]
class TasksController < ApplicationController before_action :set_task, only: [:show, :edit, :update, :destroy] def index @q = current_user.tasks.ransack(params[:q]) @tasks = @q.result(distinct: true).recent.page(params[:page]).per(10) end def todo @q = current_user.tasks.where(done: false).ransack(params[:q]) @tasks = @q.result(distinct: true).recent.page(params[:page]).per(10) end def done @q = current_user.tasks.where(done: true).ransack(params[:q]) @tasks = @q.result(distinct: true).recent.page(params[:page]).per(10) end (省略)
index
の中身をtodo
とdone
に移植します。
そして
todo
には、where(done: false
を加えるdone
には、where(done: true)
を加える移植が終わったら
indexアクション
を消す
これで、コントローラの準備はOk
Viewの実装
viewを修正していくう
まずは、tasks/index.html.slim
[ tasks/index.html.slim ]
ul.nav.nav-tabs.mb-3 li.nav-item = link_to '新規登録', new_task_path, class: 'nav-link' li.nav-item = link_to 'Todoリスト', todo_tasks_path, class: 'nav-link' li.nav-item = link_to 'Doneリスト', done_tasks_path, class: 'nav-link' .row.justify-content-end = search_form_for @q do |f| .form-inline = f.label :title_cont, 'タイトル', class: 'my-1 mr-2' = f.search_field :title_cont, class: 'my-1 mr-sm-2 form-control' = f.submit '検索', class: 'btn btn-primary my-1' .mb-3 = paginate @tasks = page_entries_info @tasks table.table thead.thead-default tr th 状況 th タイトル th 登録日 th 編集日 th tbody - @tasks.each do |task| tr td = task.done? ? 'Done' : 'Todo' td = link_to task.title, task td = task.created_at td = task.updated_at td = link_to '編集', edit_task_path(task), class: 'btn btn-primary mr-3' = link_to '削除', task, method: :delete, data: { confirm: "タスク「#{task.title}」を削除します。よろしいですか?" }, class: 'btn btn-danger'
修正内容
h1 タスク一覧
を消すnavリンク
テーブル内th
状況
を追加テーブル内td
= task.done? ? 'Done' : 'Todo'
を追加
4カ所変更を加えました。
そしたら、2つのファイルを作成
app/tasks/todo.html.slim
app/tasks/done.html.slim
[ app/tasks/todo.html.slim ]
h1 Todo一覧 = render 'index'
[ app/tasks/done.html.slim ]
h1 Done一覧 = render 'index'
はい。
tasks/index.html.slim
をパーシャルにしてやろうか(デーモン)
tasks/index.html.slim
をrenameしてtasks/_index.html.slim
に変更します
todo一覧
done一覧
nav
のactiveのやり方がわからない・・・
次は、tasks/_form.html.slim
を変更する
= form_with model: task, local: true do |f| .form-check.mb-2 = f.label :done, class: 'form-check-label' do = f.check_box :done, class: 'form-check-input' | done .form-group = f.label :title, 'タイトル' = f.text_field :title, class: 'form-control', id: 'task_title' .form-group = f.label :description, '詳細' = f.text_area :description, class: 'form-control', id: 'task_description' .form-group = f.label :image, '画像' = f.file_field :image, class: 'form-control', id: 'task_image' = f.submit '登録', class: 'btn btn-success'
form
内に.form-check
の部分を追加
ちょっとわかりにくいがまーよし
新規登録時にdoneを付ければ、そのままdone一覧に入るし、doneを付けなければtodo一覧に入る。もちろんeditからdoenにチェックを入れればdone一覧に移動する
各ページに貼ったtasks_path
へのリンクを編集する
[ show.html.slim & edit.html.slim ]
.nav.justify-content-end - if @task.done? = link_to 'Done一覧', done_tasks_path, class: 'nav-link' - else = link_to 'Todo一覧', todo_tasks_path, class: 'nav-link'
これで、選択した@taskによってリンク先を変更することができる
ヘッダーとnew.html.slim
にあるtasks_path
へのリンクには@taskが存在しないので、todo_tasks_path
を指定する
今回は以上です。
ありがとうございました!
次回、タイムゾーンを日本時間にする