この記事のゴール
- Laravel で指定した条件のレコードを取得する
- 取得したレコードの情報をブラウザで表示できるようにする。
前提条件
- Laravel のコントローラーでモデル経由でデータ取得できる状態。
※前回の記事を参考にしてください。
これからやる作業
- コントローラー編集
- ルーティング
- Bladeテンプレート作成
- ブラウザで表示確認
コントローラー編集
前回の記事で作成した [app/Http/Controllers/TodoController.php] を開いて編集します。
18行目~24行目を追記して保存してください。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Todo;
class TodoController extends Controller
{
public function index()
{
return view('todo.index', [
'pageTitle' => 'TODOリスト',
'todos' => Todo::all(),
]);
}
public function retrieve($id)
{
return view('todo.detail', [
'pageTitle' => 'TODO詳細',
'todo' => Todo::find($id),
]);
}
}
retrieve() メソッドでは引数 $id を受け取って、主キーとしてレコード検索した結果を
Bladeテンプレートに渡すようにしています。
ルーティング
[routes/web.php] を開いて編集します。
まず、4行目あたりに、次の行を追記してください。
use App\Http\Controllers\TodoController;
![](https://macocci7.net/blog/wp-content/uploads/2023/05/retrieve02-1.png)
これを追記することで、次のコントローラー指定の行を短くすることができます。
いままでは App\Http\Controllers\TodoController のように長い名称で指定していましたが、
ここで use 宣言をすることで、 TodoController だけでクラス指定できるようになります。
次に、前回追記した /todo のルーティングの箇所は、削除するかコメントアウトしてください。
その上で、次の4行を追記してください。
Route::prefix('/todo')->name('todo.')->group(function () {
Route::get('/', [TodoController::class, 'index'])->name('index');
Route::get('/{id}', [TodoController::class, 'retrieve'])->whereNumber('id')->name('detail');
});
![](https://macocci7.net/blog/wp-content/uploads/2023/05/retrieve03.png)
preifx() メソッドで、/todo をURLの前方(左側)に含むルーティングを
その後にまとめることができます。
name() メソッドで、その対象のルーティングに別名を設定することができます。
コントローラーやBladeテンプレートの中で、このルーティングを別名で呼び出すことができます。
todo.index → /todo/
todo.detail (この後にid指定が必用)→ /todo/{id}
で対応しています。
/todo/{id} の「{id}」の部分は、ブラケット内部の文字列が変数名となり、
コントローラーの指定したメソッドに引数で渡されるようになっています。
whereNumber(‘id’) の部分は、引数{id}の値が数のときだけルーティングを有効にする指定です。
引数が数でない場合は「404 NOT FOUND」になります。
Bladeテンプレート作成
フォルダ [resources/views/todo] の中に、
新しいファイル [detail.blade.php] を作成してください。
次のように編集して保存してください。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{$pageTitle}}</title>
</head>
<body>
<h1>{{$pageTitle}}</h1>
@isset($todo)
<p>
やること: {{$todo->todo}}<br />
状態:{{$todo->done ? '完了' : '未完'}}
</p>
@else
<p>情報がありません。</p>
@endisset
<a href="{{route('todo.index')}}">todo一覧</a>
</body>
</html>
17行目の「todo一覧」のリンク先のURL指定が route(‘todo.index’) になっています。
これで、具体的なURLを意識しなくても、この関数が自動で置き換えてくれます。
こうすることで、URL指定のミスが少なくなります。また、URLの変更にも強くなります。
[resources\views\todo\index.blade.php] も編集しておきましょう。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{$pageTitle}}</title>
</head>
<body>
<h1>{{$pageTitle}}</h1>
@isset($todos)
@foreach($todos as $todo)
<p>
{{$todo->id}}:{{$todo->todo}} {{$todo->done ? '[完了]' : ''}}
<a href="{{route('todo.detail', ['id' => $todo->id])}}">詳細</a>
</p>
@endforeach
@else
<p>todoは登録されていません。</p>
@endisset
</body>
</html>
13行目で詳細ページのURL呼出をしていますが、idのようなパラメータが必用なときには、
reoute('todo.detail', ['id' => $todo->id])
のように、エイリアス(別名)の後ろに、第二引数としてパラメータをハッシュ配列で渡します。
ブラウザで表示確認
ブラウザのアドレスバーに http://localhost/todo/ を入力してアクセスしてください。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/retrieve04.png)
一覧の右側に詳細ページへのリンクがあるので、クリックしてください。
![](https://macocci7.net/blog/wp-content/uploads/2023/05/retrieve05.png)
詳細ページが表示されました。
「todo一覧」をクリックして、また一覧ページが表示されたらOKです。
今回は以上です。お疲れさまでした。
コメント