Laravelでtodoアプリ

Laravel

LaravelはPHPのフレームワークで有名です。

2011年にリリースされた新しいフレームワークですが、世界中に普及しています。

ECサイトや予約システム使用されることが多いです。

MVC

Model View Controllerパーツに分割して実装していくモデルです。

  • Model
    • データの処理、DBとのやりとりを行う
  • View
    • ユーザーに画面を表示
    • ユーザからの入力を受け付ける
  • Controller
    • ユーザからの入力をModelに依頼
    • Modelが処理したデータをViewに表示を依頼

使われているフレームワーク

PHP:Laravel、CakePHP、CodeIgniter、ZendFramework

JavaScript:Backbone.js、Spine.js、JavaScriptMVC

Laravel 利用方法 2024/02/24

https://b-risk.jp/blog/2022/08/laravel/の記事の流れで実施

  • Windows
  • MAMPダウンロード済み

Composerをインストール(Windows)

https://weblabo.oscasierra.net/php-composer-windows-install/を参考

Windows PowerShellでインストールを確認 ※一度開きなおす

composer -V

Composerをインストール(Mac)

下記記事を参考 ※homebrewでComposerをインストール

Laravelをインストール

laravel_testディレクトリを作成

laravel_testに移動

composer create-project --prefer-dist laravel/laravel . "9.*"

エラー発生

php.iniファイルの編集が必要みたいです

php.iniのパス

php --ini

参考 【PHP/Linux】php.ini の探し方と修正方法:https://developer.same-san.com/detail/php-ini

php.iniのパスをみてみるとphp.iniはなく下記のベースファイル2種があります

  • php.ini-production
  • php.ini-development

php.iniを編集

2ヵ所:を削除

extension=curl
;extension=ffi
;extension=ftp
extension=fileinfo
;extension=gd
;extension=gettext
;extension=gmp

始め上記のコメントアウトのみ実施したら、再度エラー

エラー内容から検索した記事を参考に別の箇所をコメントアウト

Laravelインストール時に出たzipのエラー解決備忘録:https://qiita.com/nejimawaso/items/55512b40b724e35880c3

;extension=soap
;extension=sockets
;extension=sodium
;extension=sqlite3
;extension=tidy
;extension=xsl
extension=zip

;zend_extension=opcache

再度Laravelインストールのためのコマンドを入力

composer create-project --prefer-dist laravel/laravel . "9.*"

↓無事インストール完了

Laravelの簡易サーバを立ち上げ

php artisan serve

「http://127.0.0.1:8000/」にアクセスすると画面が表示されます。

Laravelの初期設定

laravel_test/config/app.php


'timezone' => 'Asia/Tokyo',


'locale' => 'ja',

'fallback_locale' => 'ja',

'faker_locale' => 'ja_JP',

laravel_test/.env
(主に定数を設定しているファイル)


APP_NAME=Laravel_Test

laravel_test/.resources/views/welcome.blade.php

        <!-- <title>Laravel</title> -->
        <title>{{ config('app.name') }}</title>

タイトルがLaravelからLaravel_Testに変更されます

データベース接続情報の設定

MAMPでデータベースの作成

  1. MAMP で「Open WebStart page」クリック
  2. ブラウザに表示されたhttp://localhost:8888/MAMP/のメニューの「TOOLS」の「PHPMYADMIN
  3. New」をクリック
  4. DB作成画面でデータベース名は「laravel_test」、照合順序は「utf8_general_ci」にして、「Create

データベースの情報を「.env」で変更


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_test
DB_USERNAME=root
DB_PASSWORD=root

config/database.php」を編集

デフォルトでも問題ない

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_general_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

変更を反映

※php artisan serveを実行している状態であれば、「Ctrl + C」で停止

php artisan config:clear

反映後DB接続を確認するため

php artisan migrateコマンドで確認するとエラー発生

Illuminate\Database\QueryException

エラー解決のためphp.iniを変更

;extension=pdo_firebird
extension=pdo_mysql
;extension=pdo_oci

Illuminate\Database\QueryException
再度同エラー発生

エラー内容のSQLSTATE[HY000] [2002] php_network_getaddresses: を調べたところデータベース接続ができていない

.envファイルを開きデータベース情報を修正する必要があるとのこと

改めてMySQLに接続してデータベース情報を確認
→http://localhost:8888/MAMP/?language=Japanese

上記を参考に.envを再度編集

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel_test
DB_USERNAME=root
DB_PASSWORD=root

php artisan config:clear php artisan migrate

▼コマンドを実行すると下記の通りで正しく接続できたようです

PS C:\Users\xxxx\laravel_test> php artisan migrate     

   INFO  Preparing database.

  Creating migration table ....................................................................................... 94ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table .......................................................................... 135ms DONE
  2014_10_12_100000_create_password_resets_table ................................................................ 161ms DONE
  2019_08_19_000000_create_failed_jobs_table .................................................................... 142ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ......................................................... 187ms DONE

PS C:\Users\xxxx\laravel_test> 

▼phpMyAdminにて更新すると下記の通り反映できてました(コピペで見づらいです、、)

Containing the word: 
Table Ascending	Action	Rows 	Type	Collation	Size	Overhead
	failed_jobs	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
	migrations	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	4	InnoDB	utf8_general_ci	16.0 KiB	-
	password_resets	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
	personal_access_tokens	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
	users	 	Browse Browse	Structure Structure	Search Search	Insert Insert	Empty Empty	Drop Drop	0	InnoDB	utf8_general_ci	16.0 KiB	-
5 tables	Sum	4	InnoDB	utf8_general_ci	80.0 KiB	0 B

基本的なLaravelのMVC

モデルを作成する

「todo_lists」というテーブルを作成

モデルマイグレーションファイルコントローラーを同時に作成

php artisan make:model TodoList -mc

下記の通り3つのファイルを作成されます

   INFO  Model [C:\Users\xxxxxx\laravel_test\app/Models/TodoList.php] created successfully.

   INFO  Migration [C:\Users\xxxxxx\laravel_test\database\migrations/2024_02_27_120807_create_todo_lists_table.php] created successfully.

   INFO  Controller [C:\Users\xxxxxx\laravel_test\app/Http/Controllers/TodoListController.php] created successfully.
database\migrationsフォルダ内に作成された「日付_create_todo_lists_table.php」を編集
    public function up()
    {
        Schema::create('todo_lists', function (Blueprint $table) {
            $table->id();
            $table->string('name', 100); //追記
            $table->timestamps();
        });
    }

php artisan migrateコマンドを実行

phpMyAdminにて「todo_lists」というテーブルが作成

ダミーデータを登録

シーダー

php artisan make:seeder TodoListSeederコードを実行

database\seedersにTodoListSeeder.phpが作成されます

TodoListSeeder.phpを編集

<?php
 
namespace Database\Seeders;
 
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; //追記
 
class TodoListSeeder extends Seeder
{
  /**
   * Run the database seeds.
   *
   * @return void
   */
  public function run()
  {
    DB::table('todo_lists')->insert(
      [
        [
          'name' => 'テスト1',
          'created_at' => now(),
          'updated_at' => now(),
        ],
        [
          'name' => 'テスト2',
          'created_at' => now(),
          'updated_at' => now(),
        ],
        [
          'name' => 'テスト3',
          'created_at' => now(),
          'updated_at' => now(),
        ],
      ]
    );
  }
}

database\seeders\DatabaseSeeder.phpを編集

public function run()
{
  $this->call([
    TodoListSeeder::class
  ]);
}

php artisan db:seed --class=TodoListSeeder

ダミーデータが作成されます

コントローラーを作成

app\Http\Controllersフォルダ内のTodoListController.phpを編集

編集内容:ModelクラスのTodolistからデータを取得→取得した値をViewに渡す処理

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\TodoList;//追記

class TodoListController extends Controller
{
  public function index(Request $request)
  {
    $todo_lists = TodoList::all();

    return view('todo_list.index', ['todo_lists' => $todo_lists]);
  }
}

参考:https://rocomadejapan.com/?cat=30

ビューファイルを作成

resources\views\todo_list\index.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>テスト</title>
</head>
 
<body>
 
    @if ($todo_lists->isNotEmpty())
        <ul>
            @foreach ($todo_lists as $item)
                <li>
                    {{ $item->name }}
                </li>
            @endforeach
        </ul>
    @endif
 
</body>
 
</html>

ルーティングを設定

routes\web.phpに追記

<?php

use Illuminate\Support\Facades\Route;

use App\Models\TodoList;//追記
use App\Http\Controllers\TodoListController;//追記

/*
|--------------------------------------------------------------------------
| 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('/list', [TodoListController::class, 'index']);

php artisan serveを実行しhttp://127.0.0.1:8000/listにアクセスすると正しく表示されます

TailwindCSSを導入

先ほどのセクションの続きでTailwindCSSを導入します

laravelディレクトリでnpm install -D tailwindcss postcss autoprefixerを実行

続いてnpx tailwindcss init -p実行

tailwind.config.jspostcss.config.js作成

▼tailwind.config.jsを編集

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: [
        "./resources/**/*.blade.php",
        "./resources/**/*.js",
        "./resources/**/*.vue",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

▼resources\css\app.cssを編集

@tailwind base;
@tailwind components;
@tailwind utilities;

参考サイトにはnpm run devを実行とありますが、php artisan serveコマンドも起動していないとページが表示できません

中断してphp artisan serveを実行してサイト表示させるとVite manifest not found atというエラー

npm run buildコマンドを実行する

参考:https://rocomadejapan.com/?p=1035

npm run devを実行していない時には、Vite側で、manifest.jsonファイルの情報を元に、public/build/assetsのファイルを参照してくれます。

php artisan serveでサイトが正しく表示されます

Todoアプリ実装

tasksテーブル作成

php artisan make:migration create_tasks_table

→database/migrations/日付_create_tasks_table.phpが作成されます

▼日付_create_tasks_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('name', 100);
            $table->boolean('status')->default(false);
            $table->timestamp('updated_at')->useCurrent()->nullable();
            $table->timestamp('created_at')->useCurrent()->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tasks');
    }
};

php artisan migrate実行するとphpMyAdminにてtasksテーブルが正しく作成されているのが確認できます

Taskモデルを作成

php artisan make:model Task

→app\Models\Task.phpが作成されます

コントローラーを作成

php artisan make:controller TaskController --resource

→app\Http\Controllers\TaskController.phpが作成されます

ルート情報を追記

▼routes/web.php

use App\Http\Controllers\TaskController;

Route::resource('tasks', TaskController::class);

php artisan route:listメソッドを確認

  GET|HEAD        / ........................................................................................................................................... 
  POST            _ignition/execute-solution .................................... ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
  GET|HEAD        _ignition/health-check ................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
  POST            _ignition/update-config ............................................. ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
  GET|HEAD        api/user .................................................................................................................................... 
  GET|HEAD        list ............................................................................................................... TodoListController@index
  GET|HEAD        sanctum/csrf-cookie ....................................................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
  GET|HEAD        tasks .................................................................................................... tasks.index › TaskController@index
  POST            tasks .................................................................................................... tasks.store › TaskController@store
  GET|HEAD        tasks/create ........................................................................................... tasks.create › TaskController@create
  GET|HEAD        tasks/{task} ............................................................................................... tasks.show › TaskController@show
  PUT|PATCH       tasks/{task} ........................................................................................... tasks.update › TaskController@update
  DELETE          tasks/{task} ......................................................................................... tasks.destroy › TaskController@destroy
  GET|HEAD        tasks/{task}/edit .......................................................................................... tasks.edit › TaskController@edit

                                                                                                                                            Showing [14] routes

ビューを作成を作成

▼resources/views/tasks/index.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">
        <div class="max-w-7xl mx-auto px-4 sm:px-6">
            <div class="py-[100px]">
                <p class="text-2xl font-bold text-center">今日は何する?</p>
                <form action="/tasks" method="post" class="mt-10">
                  @csrf

                  <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"
                            placeholder="洗濯物をする..." type="text" name="task_name" />
                    </label>

                    <button type="submit" class="mt-8 p-4 bg-slate-800 text-white w-full max-w-xs hover:bg-slate-900 transition-colors">
                        追加する
                    </button>
                  </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>

▼TaskController.phpを編集

    public function index()
    {
        return view('tasks.index');
    }

php artisan serveで確認したところTailwindCSSが読み込まれていない

▼参考:https://rocomadejapan.com/?p=1038

一度サーバを停止しnpm run buildを実行し再度php artisan serveで確認すると正しく表示されました

タスクを登録

▼TaskController.phpを編集

    public function store(Request $request)
    {
        $task_name = $request->input('task_name');
        dd($task_name);
    }

テストですと入力してみるとテストです” // app/Http/Controllers/TaskController.php:38と表示されstoreメソッドに渡されているのが確認できます

storeメソッド内で受け取った値をDBへ保存する設定

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Task;//追加

▼TaskController.phpを編集

public function store(Request $request)
{
  //モデルをインスタンス化
  $task = new Task;
 
  //モデル->カラム名 = 値 で、データを割り当てる
  $task->name = $request->input('task_name');
 
  //データベースに保存
  $task->save();
 
  //リダイレクト
  return redirect('/tasks');
 
}

再度テストですと入力してみるとphpMyAdminを開いてtasksテーブルに登録されているのが確認きます

バリデーション

Validatorクラスを利用

▼TaskController.phpに以下を追記

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Task;//追加
use Illuminate\Support\Facades\Validator;//追加

class TaskController extends Controller
{
   …省略…

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $rules = [
            'task_name' => 'required|max:100',
        ];
        
        $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
        
        Validator::make($request->all(), $rules, $messages)->validate();

        //モデルをインスタンス化
        $task = new Task;

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

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

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

   …省略…

▼resources\views\todo_list\index.blade.phpに追記
※labelの中にあるinputタグの下

@error('task_name')
  <div class="mt-3">
      <p class="text-red-500">
          {{ $message }}
      </p>
  </div>
@enderror

入力画面にて以下の通り正しく表示確認できます。
・何も記入しないで追加→「必須項目です」の表示
・100文字以上で入力「100文字以下にしてください。」の表示

タスクを表示

▼TaskController.phpに以下を追記

    public function index()
    {
        $tasks = Task::all();
        
        return view('tasks.index', compact('tasks'));
    }

▼resources\views\todo_list\index.blade.phpに追記

{{-- 追記 --}}
  @if ($tasks->isNotEmpty())
      <div class="max-w-7xl mx-auto mt-20">
          <div class="inline-block min-w-full py-2 align-middle">
              <div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
                  <table class="min-w-full divide-y divide-gray-300">
                      <thead class="bg-gray-50">
                          <tr>
                              <th scope="col"
                                  class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900">
                                  タスク</th>
                              <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
                                  <span class="sr-only">Actions</span>
                              </th>
                          </tr>
                      </thead>
                      <tbody class="divide-y divide-gray-200 bg-white">
                          @foreach ($tasks as $item)
                              <tr>
                                  <td class="px-3 py-4 text-sm text-gray-500">
                                      <div>
                                          {{ $item->name }}
                                      </div>
                                  </td>
                                  <td class="p-0 text-right text-sm font-medium">
                                      <div class="flex justify-end">
                                          <div>
                                              <form action="/tasks/{{ $item->id }}"
                                                  method="post"
                                                  class="inline-block text-gray-500 font-medium"
                                                  role="menuitem" tabindex="-1">
                                                  @csrf
                                                  @method('PUT')
                                                  <button type="submit"
                                                      class="bg-emerald-700 py-4 w-20 text-white md:hover:bg-emerald-800 transition-colors">完了</button>
                                              </form>
                                          </div>
                                          <div>
                                              <a href="/tasks/{{ $item->id }}/edit/"
                                                  class="inline-block text-center py-4 w-20 underline underline-offset-2 text-sky-600 md:hover:bg-sky-100 transition-colors">編集</a>
                                          </div>
                                          <div>
                                              <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>
                                          </div>
                                      </div>
                                  </td>
                              </tr>
                          @endforeach
                      </tbody>
                  </table>
              </div>
          </div>
      </div>
  @endif
  {{-- 追記ここまで --}}

※先ほど同様一度サーバを停止しnpm run buildを実行し再度php artisan serveでスタイルが効きます

タスクを編集

▼TaskController.phpに以下を追記

    public function edit($id)
    {
        $task = Task::find($id);
        return view('tasks.edit', compact('task'));
    }

▼resources/views/tasks/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>

▼TaskController.phpに以下を追記

    public function update(Request $request, $id)
    {
        $rules = [
            'task_name' => 'required|max:100',
          ];
        
          $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
        
          Validator::make($request->all(), $rules, $messages)->validate();
        
        
          //該当のタスクを検索
          $task = Task::find($id);
        
          //モデル->カラム名 = 値 で、データを割り当てる
          $task->name = $request->input('task_name');
        
          //データベースに保存
          $task->save();
        
          //リダイレクト
          return redirect('/tasks');
    }

タスクを完了

▼resources\views\todo_list\index.blade.phpに追記

<form action="/tasks/{{ $item->id }}"
    method="post"
    class="inline-block text-gray-500 font-medium"
    role="menuitem" tabindex="-1">
    @csrf
    @method('PUT')
 
    {{-- 追記 --}}
    <input type="hidden" name="status" value="{{$item->status}}">
    {{-- 追記 --}}
 
    <button type="submit"
        class="bg-emerald-700 py-4 w-20 text-white md:hover:bg-emerald-800 transition-colors">完了</button>
</form>

▼TaskController.phpに以下を追記

  public function update(Request $request, $id)
  {
  
    dd($request->status);//追記

デバッグとして完了ボタンを押すと、下記の通り0が取得でき、
編集画面で編集するボタンを押すとnullが取得でき成功が確認

デバッグでstatusの値の取得が確認できたので、
▼TaskController.phpを編集

  public function update(Request $request, $id)
  {
  
    //「編集する」ボタンをおしたとき
    if ($request->status === null) {
      $rules = [
        'task_name' => 'required|max:100',
      ];
  
      $messages = ['required' => '必須項目です', 'max' => '100文字以下にしてください。'];
  
      Validator::make($request->all(), $rules, $messages)->validate();
  
  
      //該当のタスクを検索
      $task = Task::find($id);
  
      //モデル->カラム名 = 値 で、データを割り当てる
      $task->name = $request->input('task_name');
  
      //データベースに保存
      $task->save();
    } else {
      //「完了」ボタンを押したとき
  
      //該当のタスクを検索
      $task = Task::find($id);
  
      //モデル->カラム名 = 値 で、データを割り当てる
      $task->status = true; //true:完了、false:未完了
  
      //データベースに保存
      $task->save();
    }
  
  
    //リダイレクト
    return redirect('/tasks');
  }

完了するボタンを押すとphpmyadminにてstatusが1に変更されているのが確認できます

一覧表示で未完了だけ表示

▼TaskController.phpを編集

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

タスクを削除

<div>
  <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>
</div>

   …省略…

   <script>
    function deleteTask() {
        if (confirm('本当に削除しますか?')) {
            return true;
        } else {
            return false;
        }
    }
  </script>
</body>

▼TaskController.phpを編集

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