完了、編集、削除処理を一気にいきます。
編集
前回、
[編集] :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');
}
}
終わりに
このチュートリアルは全体をさらっとなめる感じの内容だった。
認証やユーザー管理なんかには触れていない。
そこで、次回からはもう少し深く掘り下げて網羅的に学べるチュートリアルに挑戦していく。
コメント