[Laravel挑戦] 実装演習4

未分類

完了、編集、削除処理を一気にいきます。

編集

前回、

[編集] :formタグではなく、Aタグで”/tasks/{{ $item->id }}/edit/”を指定。チュートリアルブログでは、「これは、リソースコントローラーのeditメソッドを呼び出し、editメソッド内で編集画面のビュー(この後作成します)を返すようにするためです。」とあるが、今は理解できない。

と記載した。

AタグのハイパーリンクはGETメソッドとなるので、Aタグで上記のリンクを踏ませると、editメソッド処理に入る。

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
        $task = Task::find($id);
        return view('tasks.edit',compact('task'));
    }

Aタグで指定されたidを受けて、該当するTaskを検索する。

結果を$taskに入れ、views/tasks/以下のedit.blade.phpにビュー処理をリダイレクトする。

edit.blade.phpは以下のとおり。

<!DOCTYPE html>
<html lang="ja">

<head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Todo</title>
  
      @vite('resources/css/app.css')
  </head>
  
  <body class="flex flex-col min-h-[100vh]">
      <header class="bg-slate-800">
          <div class="max-w-7xl mx-auto px-4 sm:px-6">
              <div class="py-6">
                  <p class="text-white text-xl">Todoアプリ-編集画面</p>
              </div>
          </div>
      </header>
  
      <main class="grow grid place-items-center">
          <div class="w-full mx-auto px-4 sm:px-6">
              <div class="py-[100px]">
                  <form action="/tasks/{{ $task->id }}" method="post" class="mt-10">
                      @csrf
                      @method('PUT')
  
                      <div class="flex flex-col items-center">
                          <label class="w-full max-w-3xl mx-auto">
                              <input
                                  class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-4 pl-4 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm"
                                  type="text" name="task_name" value="{{ $task->name }}" />
                              @error('task_name')
                                  <div class="mt-3">
                                      <p class="text-red-500">
                                          {{ $message }}
                                      </p>
                                  </div>
                              @enderror
                          </label>
  
                          <div class="mt-8 w-full flex items-center justify-center gap-10">
                              <a href="/tasks" class="block shrink-0 underline underline-offset-2">
                                  戻る
                              </a>
                              <button type="submit"
                                  class="p-4 bg-sky-800 text-white w-full max-w-xs hover:bg-sky-900 transition-colors">
                                  編集する
                              </button>
                          </div>
                      </div>
  
                  </form>
  
              </div>
          </div>
      </main>
      <footer class="bg-slate-800">
          <div class="max-w-7xl mx-auto px-4 sm:px-6">
              <div class="py-4 text-center">
                  <p class="text-white text-sm">Todoアプリ</p>
              </div>
          </div>
      </footer>
  </body>
  
  </html>

ポイントは、formタグ内の記述だろう。

                  <form action="/tasks/{{ $task->id }}" method="post" class="mt-10">
                      @csrf
                      @method('PUT')
  
                      <div class="flex flex-col items-center">
                          <label class="w-full max-w-3xl mx-auto">
                              <input
                                  class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-4 pl-4 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm"
                                  type="text" name="task_name" value="{{ $task->name }}" />
                              @error('task_name')
                                  <div class="mt-3">
                                      <p class="text-red-500">
                                          {{ $message }}
                                      </p>
                                  </div>
                              @enderror
                          </label>
  
                          <div class="mt-8 w-full flex items-center justify-center gap-10">
                              <a href="/tasks" class="block shrink-0 underline underline-offset-2">
                                  戻る
                              </a>
                              <button type="submit"
                                  class="p-4 bg-sky-800 text-white w-full max-w-xs hover:bg-sky-900 transition-colors">
                                  編集する
                              </button>
                          </div>
                      </div>
  
                  </form>

tasks/{{id}}に @method(‘PUT’) で明示的にメソッドを指定することで、updateメソッド処理になる。

updateメソッドはこんな感じ。

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
        $rules = [
            'task_name' => 'required|max:10',
        ];

        $messages = ['required' => '必須項目です', 'max' => '10文字以下にして'];

        Validator::make($request->all(),$rules,$messages)->validate();

        // dd('ここきた');

        // モデルをインスタンス化
        $task = Task::find($id);

        // モデル->カラム名 = 値 で、データを割り当てる
        $task->name = $request->input('task_name');

        // データベースに保存
        $task->save();

        // リダイレクト
        return redirect('/tasks');
    }

追加処理(storeメソッド)とほぼ同じ処理だが、save対象タスクが既存タスクをfind()した上で書き換えをしているのがわかる。

完了

そのタスクが終わったことを示す状態に移すのが完了。

tasksテーブルのstatusカラムの値をデフォルトのfalseからtrueにする。

そのためには、updateメソッドを使いたいが、編集処理にも使っているので、工夫が必要だ。

どんな工夫かと思っていたらチュートリアルブログではformタグにhiddenを追加するやり方を紹介していた。

こんな感じ。

<input type="hidden" name="status" value="{{ $item->status }}">

また、@method(‘PUT’)をformタグ内でわざわざ指定して、POSTメソッドから変更している。

これは、新規作成するPOSTメソッドに対して、更新処理をするPUTメソッドを指定するためで、HTMLタグにPUTがないのでBladeテンプレートエンジンの構文で定義されているもの。

さきほどの編集の処理と完了の処理を記載したのが以下となる。

    public function update(Request $request, $id)
    {
        //
        if ($request->status == null) { // 編集
            $rules = [
                'task_name' => 'required|max:10',
            ];
    
            $messages = ['required' => '必須項目です', 'max' => '10文字以下にして'];
    
            Validator::make($request->all(),$rules,$messages)->validate();
    
            // dd('ここきた');
    
            // モデルをインスタンス化
            $task = Task::find($id);
    
            // モデル->カラム名 = 値 で、データを割り当てる
            $task->name = $request->input('task_name');
    
            // データベースに保存
            $task->save();
    
        }
        else {
            // 完了処理
            $task = Task::find($id);
            $task->status = true;
            $task->save();
        }

        // リダイレクト
        return redirect('/tasks');    
    }

index表示を未完了のみにする

これだけ。

    public function index()
    {
        //
        //$tasks = Task::all();
        $tasks = Task::where('status',false)->get();
        return view('tasks.index',compact('tasks'));
    }

対象クラスにwhereでカラム文字列指定して、検索したい値をget()する。

タスクの削除処理

現状の「削除」ボタンは以下のようになっていて、ルーティングによりdestroyメソッドに処理が送られる。

だから、そこに処理を書けばよさそうなものだがチュートリアルブログは違うことをやっている。

<form action="/tasks/{{ $item->id }}" method="post"
  class="inline-block text-gray-500 font-medium"
  role="menuitem" tabindex="-1">
  @csrf
  @method('DELETE')
  <button type="submit"
    class="py-4 w-20 md:hover:bg-slate-200 transition-colors">削除</button>
</form>

と思ったら、単に一旦ダイアログを出して削除の意思確認するだけだった。

<form onsubmit="return deleteTask();" action="/tasks/{{ $item->id }}" method="post"
    class="inline-block text-gray-500 font-medium"
    role="menuitem" tabindex="-1">
    @csrf
    @method('DELETE')
    <button type="submit" class="py-4 w-20 md:hover:bg-slate-200 transition-colors">削除</button>
</form>

<script>
  function deleteTask() {
    if (confirm('削除する?')) {
      return true;  // 確認した場合、フォームが送信される
    } else {
      return false; // キャンセルの場合、フォーム送信が中止される
    }
  }
</script>

TaskControllerでdestroyメソッドを書くだけ。

    public function destroy($id)
    {
        //
        //dd("destroy{$id}.");
        Task::find($id)->delete();
        return redirect('/tasks');
    }
}

終わりに

このチュートリアルは全体をさらっとなめる感じの内容だった。

認証やユーザー管理なんかには触れていない。

そこで、次回からはもう少し深く掘り下げて網羅的に学べるチュートリアルに挑戦していく。

コメント

PHP Code Snippets Powered By : XYZScripts.com
タイトルとURLをコピーしました