皆さん、こんにちは。管理人です。今回は作成されたタスクの一覧をダッシュボードの画面に表示し、タスクを削除する機能も実装したいと思います。
作成されたタスクをダッシュボードに表示する
このセクションでは(ログイン中のユーザーによって)作成されたタスクのタイトル一覧がダッシュボードに表示されるようにしたいと思います。
まず、routes/web.php
を開き、次のように編集して下さい。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TaskController;
/*
|--------------------------------------------------------------------------
| 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('/dashboard', [TaskController::class, 'show'])->middleware(['auth'])->name('dashboard');
// 編集ここまで
Route::post('/store', [TaskController::class, 'store'])->middleware(['auth'])->name('store');
require __DIR__.'/auth.php';
続いて、TaskController の show アクション(GET)を実装したいと思います。app/Http/Controllers/TaskController.php
を次のように編集して下さい。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
class TaskController extends Controller
{
public function store(Request $request)
{
$data = $request->all(); // フォームで送信されたデータをすべてとってきます
Task::insertGetId([
'user_id' => \Auth::id(), // ログイン中のユーザーの ID を格納します
'title' => $data['title'], // 入力された文字列を格納します
]);
return redirect()->route('dashboard'); // 処理が終わったらダッシュボードにリダイレクトします
}
// 追記ここから
public function show()
{
$tasks = Task::where('user_id', \Auth::id())->get(); // ログイン中のユーザーが作成したタスクをすべてとってきます
return view('dashboard', compact('tasks')); // ここではビューに変数を渡しています
} // 追記ここまで
}
ここで 26 行目に「ビューに変数を渡」すという表現が出てきました。上の TaskController.php の 26 行目では、PHP の compact
という関数を使って dashboard というビューに変数 $tasks を渡しているのです。そうすることによって、次の dashboard.blade.php
内で変数 $tasks
を使うことができるようになります。
それでは、resources/views/dashboard.blade.php
を次のように編集して下さい。
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-5">
<div class="max-w-3xl mx-auto px-4">
<form class="grid grid-cols-1 gap-3" method='POST' action="/store" enctype="multipart/form-data">
@csrf
<label class="block">
<span class="text-gray-700">新しいタスク</span>
<input name="title" type="text" class="mt-2 block w-full rounded-md border-gray-300 shadow-sm">
</label>
<button type='submit' class="w-20 bg-blue-600 hover:bg-blue-500 text-white rounded px-4 py-2">作成</button>
</form>
<!-- 追記ここから -->
@foreach ($tasks as $task)
<div>{{ $task['title'] }}</div>
@endforeach
<!-- 追記ここまで -->
</div>
</div>
</x-app-layout>
ここで
@foreach ($tasks as $task)
<div>{{ $task['title'] }}</div>
@endforeach
という記述が出てきました。この foreach
というのは、配列に含まれる各要素を順番に取り出して処理する際によく使います。ここでは、$tasks
がログイン中のユーザーがもつタスクの全体をあらわしますので、変数 $task
には、そこに含まれるタスクが順番に代入されることになります。また、二重括弧 {{ }} で変数を囲うと、その変数の値が出力されることになります。
それでは、php artisan serve と npm run dev というコマンドが実行中であることと XAMPP の MySQL が緑色になっていることを確認して、ブラウザで localhost:8000
にアクセスしてみましょう。
タスクを削除する機能を実装する
次に、タスクを削除する機能を作っていきたいと思います。resources/views/dashboard.blade.php
を次のように編集して下さい。
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<div class="py-5">
<div class="max-w-3xl mx-auto px-4">
<form class="grid grid-cols-1 gap-3" method='POST' action="/store" enctype="multipart/form-data">
@csrf
<label class="block">
<span class="text-gray-700">新しいタスク</span>
<input name="title" type="text" class="mt-2 block w-full rounded-md border-gray-300 shadow-sm">
</label>
<button type='submit' class="w-20 bg-blue-600 hover:bg-blue-500 text-white rounded px-4 py-2">作成</button>
</form>
@foreach ($tasks as $task)
<!-- 編集ここから -->
<div class="flex flex-wrap justify-between p-2 my-5 bg-green-600 rounded">
<div class="text-white">{{ $task['title'] }}</div>
<div class="flex">
<button type='submit' class="w-20 bg-blue-600 hover:bg-blue-500 text-white rounded px-4 py-2 mr-2" onclick="location.href='#'">編集</button>
<form method='POST' action="/delete/{{ $task['id'] }}" enctype="multipart/form-data">
@csrf
<button type='submit' class="w-20 bg-red-600 hover:bg-red-500 text-white rounded px-4 py-2">削除</button>
</form>
</div>
</div>
<!-- 編集ここまで -->
@endforeach
</div>
</div>
</x-app-layout>
ここでのポイントは 24 行目の
action="/delete/{{ $task['id'] }}"
です。このルーティングはまだ定義していませんが、こうすることにより、該当するタスクを削除するボタンとなります。
次にこのルーティングを定義するため、routes/web.php
に一行を加えて次のようにして下さい。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TaskController;
/*
|--------------------------------------------------------------------------
| 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('/dashboard', [TaskController::class, 'show'])->middleware(['auth'])->name('dashboard');
Route::post('/store', [TaskController::class, 'store'])->middleware(['auth'])->name('store');
Route::post('/delete/{id}', [TaskController::class, 'delete'])->middleware(['auth'])->name('delete'); // 追記
require __DIR__.'/auth.php';
ここで 23 行目に /delete/{id}
と書かれていますが、この {id}
の部分がパラメータとなり、削除するタスクの ID となります。同じく 23 行目に [TaskController::class, 'delete']
とありますので、TaskController
の delete
アクション(POST)を次のように定義しましょう。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
class TaskController extends Controller
{
public function store(Request $request)
{
$data = $request->all(); // フォームで送信されたデータをすべてとってきます
Task::insertGetId([
'user_id' => \Auth::id(), // ログイン中のユーザーの ID を格納します
'title' => $data['title'], // 入力された文字列を格納します
]);
return redirect()->route('dashboard'); // 処理が終わったらダッシュボードにリダイレクトします
}
public function show()
{
$tasks = Task::where('user_id', \Auth::id())->get();
return view('dashboard', compact('tasks'));
}
// 追記ここから
public function delete($id)
{
/** この if 文がないと、他のユーザーのタスクを削除できてしまう可能性があります */
if (Task::where('id', $id)->where('user_id', \Auth::id())->exists()) {
Task::destroy($id); // クリックされた削除ボタンに対応するタスクを削除します
return redirect()->route('dashboard'); // ダッシュボードにリダイレクトします
} else {
abort(500); // サーバーエラー
}
} // 追記ここまで
}
ここで、TaskController.php の delete アクションは
public function delete($id)
{
Task::destroy($id);
return redirect()->route('dashboard');
}
と書いてもよいのではないかと思う方もいると思います。しかしながらこれはちょっと危険です。理由は後述します。
最後に
いかがでしたでしょうか。次回は作成したタスクのタイトルを編集できるようにする機能を実装したいと思います。お疲れ様でした。
コメント