Railsのまとめ8(ToDoリストの作成2)

7から続きます

11:編集機能を追加する

app/views/tasks/new.html.erbで以下の記述を追加する

<h1>TODOアプリ</h1>
 <ul>
   <% @tasks.each do |task| %>
  <li>
   <%= check_box_tag '', '' %>
   <%= task.title %>
   <%= link_to '[編集]', edit_task_path(task.id)%>
  </li>
 <% end %>
 </ul>

edit_task_pathなのは↓のPrefixでtasks#editと関連しているため

(task.id)は/tasks/:idに埋め込まれる

Prefix    Verb    URI Pattern           Controller#Action
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
root      GET    /                         tasks#index

12:編集画面の開発

app/views/tasks/new.html.erbを複製してedit.html.erbを作成し

app/views/tasks/edit.html.erbで以下の記述を追加

<h1>編集画面</h1>
 <%= form_for @task do |f| %>
 <p>
   <%= f.label :title %>
 <br>
   <%= f.text_field :title %>
 </p>
 <p><%= f.submit %></p>
<% end %>

13:編集機能の開発

tasks_controllerに以下の記述を追加

class TasksController < ApplicationController

  def index
    @tasks = Task.all
  end

  def new
    @task = Task.new
  end

  def create
    @task = Task.new(task_params)
     if @task.save
      redirect_to root_path
     else
      render 'new'
     end
   end

   def edit
#tasksテーブルから指定されたIDのレコードを取得するという意味
     @task = Task.find(params[:id])
   end

     private

   def task_params
     params[:task].permit(:title)
   end
end

14:削除機能のViewを開発

<h1>TODOアプリ</h1>
 <ul>
 <% @tasks.each do |task| %>
 <li>
 <%= check_box_tag '', '' %>
    <%= task.title %>
<%= link_to '[編集]', edit_task_path(task.id)%>
<%= link_to '[削除]',task_path(task.id),method: :delete,data:{ confirm: '削除してもよろしいですか?'} %>
 </li>
   <% end %>
 </ul>

メソッドは:deleteを使う
task_path(task.id)なのは↓のdestroyから

DELETE  /tasks/:id(.:format) tasks#destroy

15:削除機能の開発

tasks_controllerにて以下を追加

def destroy
  @task = Task.find(params[:id])
  @task.destroy
    redirect_to root_path
end

↑Taskテーブルから指定したIDのデータを取得してインスタンス変数に代入する。該当するデータを削除する。
削除に成功したらルートURLに遷移する

削除ボタンを確認したらOKです

16:トグル動作の開発

Ajaxとは?
ウェブブラウザ内で非同期通信を行いながらインターフェイスの
構築を行うプログラミング手法。

つまり画面を移動(更新含む)しなくても、サーバとの通信を行いながら、
動的に画面の表示内容が変わるWebアプリが作れる技術で
GmailやGoogle mapなどが代表例

JavaScriptのライブラリ、jQueryを使用する。

jQueryのインストール
Gemfileに以下の記述を追加

gem 'jquery-rails', '~>4.3.1'

bundle install

app/javascript/application.jsに以下の記述を

//= require jquery3
//= require jquery_ujs

ルーティングの設定

config/locales/routes.rb

Rails.application.routes.draw do
  resources :tasks
  root 'tasks#index'
  post '/tasks/:id/toggle' => 'tasks#toggle'
end

postで/tasks/:idこのURLのパターンであったら
tasksコントローラーのトグルアクションメソッドを実行するという意味。

rake routesで確認↓があればOK

POST /tasks/:id/toggle(.:format) tasks#toggle

デストロイメソッドの↓に

def toggle
  head :no_content
  @task = Task.find(params[:id])
  @task.done = !@task.done
  @task.save
end

↑Ajaxのデータの通信を行いたいのでViewの通信はしないという設定

1:TasksテーブルからブラウザからAjax通信で渡されたIDを使ってレコードを検索する
2:その結果を@taskに入れる
3:該当データのカラムDoneのデータを真偽反転する。
4:TrueがFalseにFalseがTrueになる。

結論からいうと、後の@task.saveでデータをデータベースに保存するためで

task.doneはそのタスクが「終了しているか」、「終了していないか」を管理する変数なので、
真偽値を反転させるのは以下のような操作になる↓

A 終了していない(チェックボックスにチェックが入っていない)状態

↓↑

B 終了している(チェックボックスにチェックが入っている)状態

AとBの状態を切り替えるわけなんだけれども、

この切り替え処理(+(保存処理)をサーバー側(Rails)で行わないと、
HTML上でだけチェックがついたり外れたりするだけで、
切り替えた情報がデータベースに保存されない。

試しに、@task.done = !@task.doneの行(もしくはsaveの行)を
コメントアウトして、チェックをつけたり外したりして、
画面をリロードしてみると、
チェックの情報が保存されていないので、
チェックの情報が以前のものに戻ってしまう。

チェックボックスのトグル動作のクライアント側を開発しよう!

17:トグルメソッドにデータをポストする処理を記述

<h1>TODOアプリ</h1>
<ul>
  <% @tasks.each do |task| %>
   <li>
     <%= check_box_tag '', '', task.done, {'data-id' => task.id } %>
      <%= task.title %>
       <%= link_to '[編集]', edit_task_path(task.id)%>
        <%= link_to '[削除]',task_path(task.id),method: :delete,
            data:{ confirm: '削除してもよろしいですか?'} %>
    </li>
   <% end %>
  </ul>
<%= link_to '新規追加', new_task_path %>
<script>
$(function(){
$("input[type=checkbox]").click(function(){
$.post('/tasks/' + $(this).data('id') + '/toggle');
});
});
</script>

data-* が意味するのは、カスタム要素で好きな値が設定できて主にJavaScriptと併用して使用される。
ここでは、jQueryのdata(‘id’)でdata-id に指定されている値を取得している。
data-* を使用しているが、hidden要素などを組み合わせれば
別の方法でも実装は可能なので、
data-* を使わなければいけないというわけではない。
data-* の * 部分は自由となるので
‘data-my-sample-id’ => task.id として
$(this).data(‘my-sample-id’) + ‘/toggle’);
としても動作します。

↑のJavaScriptでは関数名を無名にしていることによって関数式としている
$は省略構文$(セレクタ).メソッド(引数)

チェックしてリロードした時チェックが外れていなければ完成です!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です