LaravelでTodoリストを実装してみよう!~実装編2:Todo追加機能の実装~
はじめに
今回は、Todo追加機能を実装していこうと思います!
前回の記事はこちら↓
Todo追加画面の作成
まずは画面を実装していきます!
コンポーネントの作成:Todo追加ボタン
画面に配置するTodo追加ボタンを作成します。
sail artisan make:component element.button-addtodo --view
生成されたresources/views/components/element/button-addtodo.blade.php
ファイルを以下のように書き換えます。
<button
type="submit"
class="inline-flex justify-center py-2 px-4 border border-transparent
shadow-sm text-sm font-medium rounded-md text-white bg-blue-500
hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-blue-500"
>
{{ $slot }}
</button>
ビューの作成
次にビューを作っていきます。ビューの生成には、以下のコマンドを実行します。
sail artisan make:view todolist.addtodo
生成されたresources/views/todolist/addtodo.blade.php
を以下のように書き換えます。
<x-layout.layout title="Todo追加 | Todoアプリ">
<x-layout.todolist-single>
<form method="POST" action="{{ route('todolist') }}" class="justfy-center">
<div class="flex flex-col justify-center">
<div class="flex justify-center mb-4 text-4xl font-extralight text-green-500">Todo追加</div>
@csrf
<div class="flex justify-center items-center">
<div class="text-xl w-20">Todo</div>
<input type="text" name="content" placeholder="Todoを入力" class="@error('content') is-invalid @enderror w-96 ml-4 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-green-500 dark:focus:border-green-600 focus:ring-green-500 dark:focus:ring-green-600 rounded-md shadow-sm">
</div>
@error('content')
<div style="color: red" class="alert alert-danger">{{ $message }}</div>
@enderror
<div class="flex justify-center items-center mt-4">
<div class="flex text-xl w-20">期限</div>
<input type="date" name="deadline" placeholder="YYYY-MM-DD" class="@error('deadline') is-invalid @enderror flex w-96 ml-4 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-green-500 dark:focus:border-green-600 focus:ring-green-500 dark:focus:ring-green-600 rounded-md shadow-sm">
</div>
@error('deadline')
<div style="color: red" class="alert alert-danger">{{ $message }}</div>
@enderror
<div class="flex mt-4 justify-center">
<x-element.button-addtodo>追 加</x-element.button-addtodo>
</div>
</div>
</form>
</x-layout.todolist-single>
</x-layout.layout>
<form method="POST" action="{{ route('todolist') }}" class="justfy-center">
の部分は便宜上既にあるtodolist
にパスをつないでいますが、後程書き換えます。
コントローラーの作成
そして、コントローラーを作成します。
コントローラーファイルの生成には、以下のコマンドを実行します。
sail artisan make:controller Todolist/AddTodo/AddTodoPageController --invokable
生成されたapp/Http/Controllers/Todolist/AddTodo/AddTodoPageController.php
ファイルを以下のように書き換えます。
<?php
namespace App\Http\Controllers\Todolist\AddTodo;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class AddTodoPageController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Request $request)
{
+ return view('todolist.addtodo');
}
}
ルーティング
最後に、ルーティングでパスをつないで完成です!
routes/web.php
に以下のコードを書き加えます。
//// 省略 ////
Route::get('addtodo-page',\App\Http\Controllers\Todolist\AddTodo\AddTodoPageController::class)
->name('addtodo-page');
http://localhost/addtodo-page
にアクセスすると以下のような画面が表示されていれば完成です!
まだTodo追加機能を実装していないので、追加ボタンを押してもエラーが出ます。
Todo追加機能の作成
続いて、追加ボタンを押したときに実際にTodoが追加されるように機能を実装していきましょう!
リクエストの作成
まず、追加ボタンを押したときに、入力した情報をコントローラーに送信できるようにリクエストを作っていきます。
リクエストファイルを生成するには以下のコマンドを実行します。
sail artisan make:request Todolist/AddTodoRquest
生成されたapp/Http/Requests/Todolist/AddTodoRquest.php
ファイルを以下のように書き換えます。
<?php
namespace App\Http\Requests\Todolist;
use Illuminate\Foundation\Http\FormRequest;
class AddTodoRquest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
- return false;
+ return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
+ 'content' => 'required',
+ 'deadline' => 'required|date',
];
}
+ public function userId() : int {
+ return $this->user()->id;
+ }
+ public function content(): string {
+ return $this->input('content');
+ }
+ public function deadline(): string {
+ return $this->input('deadline');
+ }
}
コントローラーの作成
次に、コントローラーを作成していきます。
sail artisan make:controller Todolist/AddTodo/AddTodoController --invokable
生成されたapp/Http/Controllers/Todolist/AddTodo/AddTodoController.php
を以下のように書き換えます。
<?php
namespace App\Http\Controllers\Todolist\AddTodo;
use App\Http\Controllers\Controller;
+use App\Models\Todolist;
+use App\Http\Requests\Todolist\AddTodoRquest;
-use Illuminate\Http\Request;
class AddTodoController extends Controller
{
/**
* Handle the incoming request.
*/
- public function __invoke(Request $request)
+ public function __invoke(AddTodoRquest $request)
{
+ $todo = new Todolist();
+ $todo->user_id = $request->userId();
+ $todo->content = $request->content();
+ $todo->deadline = $request->deadline();
+ $todo->save();
+ return redirect()->route('todolist');
}
}
ルーティング
routes/web.php
に以下のコードを書き加えます。
//// 省略 ////
Route::post('todo/addtodo',\App\Http\Controllers\Todolist\AddTodo\AddTodoController::class)
->name('addtodo');
ビューの修正
そして、ビューファイルの便宜上todolist
にパスをつないでいた
<form method="POST" action="{{ route('todolist') }}" class="justfy-center">
の部分を書き換えます。
<x-layout.layout title="Todo追加 | Todoアプリ">
<x-layout.todolist-single>
- <form method="POST" action="{{ route('todolist') }}" class="justfy-center">
+ <form method="POST" action="{{ route('addtodo') }}" class="justfy-center">
{{-- 省略 --}}
現状、ユーザーログイン機能を実装していないので、以下のようなエラー画面が出ます。
とりあえず追加機能を試したい人へ
現状ユーザーログインがないので、マイグレーションファイルのユーザーIDを記録するカラムにデフォルト値を設定しましょう。
public function up(): void
{
Schema::create('todolists', function (Blueprint $table) {
$table->id();
- $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
+ $table->foreignId('user_id')->default(1)->constrained('users')->cascadeOnDelete();
$table->string('content');
$table->date('deadline');
$table->boolean('status')->default(0);
$table->timestamps();
});
}
マイグレーションファイルを編集したので、マイグレーションをリフレッシュして再度シーディングもしておきましょう。
sail artisan migrate:refresh --seed
sail artisan db:seed --class=TodoSeeder
後は、リクエストとコントローラーのuserId
にかかわる部分をコメントアウトしておけば機能するようになります。
public function __invoke(AddTodoRquest $request)
{
$todo = new Todolist();
// $todo->user_id = $request->userId(); //コメントアウト
$todo->content = $request->content();
$todo->deadline = $request->deadline();
$todo->save();
return redirect()->route('todolist');
}
// public function userId() : int {
// return $this->user()->id;
// }
ファイルを保存したら、Todo追加画面を再読み込みして、追加ボタンを押すとTodoが追加されているはずです。
おわりに
今回は、Todo追加画面と機能をコーディングしました。
ユーザー認証の機能を実装していないので、このままでは動きませんが、次々回くらいの記事でログイン機能追加しようと思います!
ではまた!
Discussion