Help us understand the problem. What is going on with this article?

【Todoリスト作成】同じURLに別のpost処理をルーティングしたい

やりたいこと

下記を同時に行いたい

  • 指定したIDカラムのステータスの更新
  • 指定したIDカラムの削除 完成イメージ

発生している問題

以下のことから削除処理が優先して行われてしまう

  • 削除処理も更新処理もidを渡して行っている
  • 同じ画面にリダイレクトさせている

該当のソースコード

web.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});



Route::get('/login', 'LoginController@index');

Route::get('/register', 'RegisterController@index'); 
Route::post('/register', 'RegisterController@post');

Route::get('todos','TodosController@index');
Route::post('todos','TodosController@store');
Route::post('/todos/{id}','TodosController@update');
Route::post('/todos/{id}','TodosController@remove');

index.blade.php

@extends('layouts.parents')

@section('title', 'Todoリスト')

@section('content')
  @if(count($errors) > 0)
    <div>
      <ul>
        @foreach($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
   @endif
<h1>Todoリスト</h1>
  <label><input type="radio" checked>すべて</label>
  <label><input type="radio">作業中</label>
  <label><input type="radio">完了</label>
    <table>
      <tr>
        <th>ID</th>
        <th>コメント</th>
        <th>状態</th>
      </tr>
      @foreach($todos as $todo)
        <tr>
        <!-- findで検索されたIDを取得 -->
          <input type="hidden" name="id" value="{{$todo->id}}">
          <td>{{$loop->iteration}}</td>
          <td>{{$todo->comment}}</td>
          @if($todo->state > 0)
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @csrf
            <!-- 作業中ボタン -->
            <td><input type="submit" value="作業中"></td>
            <input type="hidden" name="state" value="0">
          </form>
          @else
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @csrf
            <!-- 完了ボタン -->
            <td><input type="submit" value="完了"></td>
            <input type="hidden" name="state" value="1">
          </form>
          @endif
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @csrf
            <!-- 削除ボタン -->
            <td><button type="submit">削除</button></td>
          </form>
        </tr>
      @endforeach
    </table>
<h1>新規タスクの追加</h1>
<form action="todos" method="POST">
  @csrf
    <input type="text" name="comment" value="{{old('comment')}}">
    <!-- 追加ボタン -->
    <input type="submit" value="追加">
</form>
@endsection

TodosController.php

<?php

namespace App\Http\Controllers;

use App\Todo;
use Illuminate\Http\Request;
use App\Http\Requests\TodoRequest;

class TodosController extends Controller
{
    //DBにあるレコードを表示する
    public function index(Request $request)
    {
        $todos =Todo::all();
        return view('todos.index', ['todos' => $todos]);
    }

    //レコードを追加する
    public function store(TodoRequest $request)
    {
        // $this->validate($request, Todo::$rules);
        $todo = new Todo;
        $form = $request->all();
        unset($form['_token']);
        $todo->fill($form)->save();
        return redirect('todos');
    }

    //state変換
    // public function edit(Request $request)
    // {
    //     $todos =Todo::all();
    //     return view('todos.boolean', ['todos' => $todos]);
    // }

    public function update(Request $request)
    {
        Todo::find($request->id)
        ->update(['state' => $request->state]);
        return redirect('todos');
    }

    // レコードを削除する
    public function remove(Request $request)
    {
        Todo::find($request->id)->delete();
        return redirect('todos');
    }

}

解決

ルート定義メソッドを修正して解決?
一応意図した挙動にはなった

参照

使用可能なルート定義メソッドの部分
https://readouble.com/laravel/5.8/ja/routing.html
FormからPUT、PATCH、DELETEリクエストを送る方法(Laravel)
https://qiita.com/kambe0331/items/ff49b175ea9d8edec8c9
POSTとPUTとPATCHの使い分けについて
https://teratail.com/questions/193410

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});



Route::get('/login', 'LoginController@index');

Route::get('/register', 'RegisterController@index');
Route::post('/register', 'RegisterController@post');

Route::get('todos','TodosController@index');
Route::post('todos','TodosController@store');
Route::patch('/todos/{id}','TodosController@update');
Route::delete('/todos/{id}','TodosController@remove');

@extends('layouts.parents')

@section('title', 'Todoリスト')

@section('content')
  @if(count($errors) > 0)
    <div>
      <ul>
        @foreach($errors->all() as $error)
          <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
   @endif
<h1>Todoリスト</h1>
  <label><input type="radio" checked>すべて</label>
  <label><input type="radio">作業中</label>
  <label><input type="radio">完了</label>
    <table>
      <tr>
        <th>ID</th>
        <th>コメント</th>
        <th>状態</th>
      </tr>
      @foreach($todos as $todo)
        <tr>
        <!-- findで検索されたIDを取得 -->
          <input type="hidden" name="id" value="{{$todo->id}}">
          <td>{{$loop->iteration}}</td>
          <td>{{$todo->comment}}</td>
          @if($todo->state > 0)
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @method('PATCH')
            @csrf
            <!-- 作業中ボタン -->
            <td><input type="submit" value="作業中"></td>
            <input type="hidden" name="state" value="0">
          </form>
          @else
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @method('PATCH')
            @csrf
            <!-- 完了ボタン -->
            <td><input type="submit" value="完了"></td>
            <input type="hidden" name="state" value="1">
          </form>
          @endif
          <form action="{{url('/todos', $todo->id)}}" method="POST">
            @method('DELETE')
            @csrf
            <!-- 削除ボタン -->
            <td><button type="submit">削除</button></td>
          </form>
        </tr>
      @endforeach
    </table>
<h1>新規タスクの追加</h1>
<form action="todos" method="POST">
  @csrf
    <input type="text" name="comment" value="{{old('comment')}}">
    <!-- 追加ボタン -->
    <input type="submit" value="追加">
</form>
@endsection

<?php

namespace App\Http\Controllers;

use App\Todo;
use Illuminate\Http\Request;
use App\Http\Requests\TodoRequest;

class TodosController extends Controller
{
    //DBにあるレコードを表示する
    public function index(Request $request)
    {
        $todos =Todo::all();
        return view('todos.index', ['todos' => $todos]);
    }

    //レコードを追加する
    public function store(TodoRequest $request)
    {
        $todo = new Todo;
        $form = $request->all();
        unset($form['_token']);
        $todo->fill($form)->save();
        return redirect('todos');
    }

    //stateを更新する
    public function update(Request $request)
    {
        Todo::find($request->id)
        ->update(['state' => $request->state]);
        return redirect('todos');
    }

    // レコードを削除する
    public function remove(Request $request)
    {
        Todo::find($request->id)
        ->delete();
        return redirect('todos');
    }

}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away