ルーティング設定
routes/web.php にアクセスがあった時の処理を記述する。
use App\Http\Controllers\ThreadController;
Route::get('/', [ThreadController::class, 'index']);
Route::resource('threads', ThreadController::class);
use App\Http\Controllers\ThreadController;
この階層にあるコントローラーを使うよ
'/'にアクセスした時に
ThreadControllerのclassである 'index'を使うよ。
ビュー作成
resources/viewsのディレクトリ(フォルダ)の中に
threads ディレクトリを作成して下記3つを作成
threads/index.blade.php
threads/create.blade.php
threads/show.blade.php
それぞれの中に記述する。
index.blade.php
@extends('layouts.app')
@section('content')
<h1>スレッド一覧</h1>
<a href="{{ route('threads.create') }}">スレッドを作成</a>
<ul>
@foreach ($threads as $thread)
<li><a href="{{ route('threads.show', $thread->id) }}">{{ $thread->title }}</a></li>
@endforeach
</ul>
@endsection
@extends('layouts.app')
このテンプレートファイルは同じ階層のlayouts/app.blade.phpを継承
layouts/app.blade.phpは共通部品の定義。
@section('content')
@yield('content')に挿入
<a href="{{ route('threads.create') }}">スレッドを作成</a>
aタグはリンクのHTMLタグ。
{{ route('threads.create') }}
route関数でthreads.createをURLとして作成
リンクさせる。
<ul>
はリストつくるよ〜のタグ
@foreach ($threads as $thread)
foreachは繰り返すよ。
何を?
$threadsという変数に含まれているデータ一つずつ。
1件ずつは$threadという変数に格納して処理するよ。
$threads(a,b,c,d,e)
1回目thread(a)で処理
終わったら
2回目thread(b)で処理
・・・
<li><a href="{{ route('threads.show', $thread->id) }}">{{ $thread->title }}</a></li>
liリストにするよー
リストはリンクにするよ。
route関数を使ってthreads.showというURLを$threadのid情報も渡して作成。
/threads/(id番号)に変換。
<a href="">文字入れられる</a>
文字入れられる場所に
{{ $thread->title }}
$threadに格納されているtitleに対応する値を呼び出し当て込む。
@endforeach
繰り返しがなくなったら終わりだ。
@endsection
ここで@yield('content')も終わり。
creat.blade.php
これはスレッドの作成ページ
@extends('layouts.app')
@section('content')
<h1>スレッド作成</h1>
<form method="POST" action="{{ route('threads.store') }}">
@csrf
<label for="title">タイトル</label>
<input type="text" name="title" id="title" required>
<button type="submit">作成</button>
</form>
@endsection
これも同じだね
@extends('layouts.app')
を継承
@section('content')
@yield('content')の場所に入れ込むよ
<form method="POST" action="{{ route('threads.store') }}">
@csrf
<label for="title">タイトル</label>
<input type="text" name="title" id="title" required>
<button type="submit">作成</button>
</form>
formは送信用のタグ。
method="POST"はサーバーに送信するための方法。ここを"get"にするとURLに文字が出てくる。
action="{{ route('threads.store') }}"
フォームの送信先のURLはthreads.store
web.phpのthreads.storeという名前付きルートを使う。
ここでちょっと引っかかる。
Route::post~~~~~
でthreads.storeなんて設定していない。
が
Route::resource('threads', ThreadController::class);
を指定することでCRUDの操作に必要なルートが自動生成される。
なのでその中にthreads.storeも含まれていた。
@endsection
それでここまでだよ〜といれて終わり。
## show.blade.php
次はスレッドの詳細ページの作成
@extends('layouts.app')
@section('content')
<h1>{{ $thread->title }}</h1>
<ul>
@foreach ($posts as $post)
<li>{{ $post->content }}</li>
@endforeach
</ul>
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<input type="hidden" name="thread_id" value="{{ $thread->id }}">
<textarea name="content" rows="3" required></textarea>
<button type="submit">投稿</button>
</form>
@endsection
これも見ていく
@extends('layouts.app')
@section('content')
<h1>{{ $thread->title }}</h1>
h1タグにタイトルを表示。
<ul>
@foreach ($posts as $post)
<li>{{ $post->content }}</li>
@endforeach
</ul>
リスト作成して。
foreachで繰り返し。
$postsを繰り返すよ。その時$postに入れて動かすよ。
$postの中のcontentを出して表示。
<form method="POST" action="{{ route('posts.store') }}">
フォーム送信時にPOSTメソッドで送信。
routeでposts.storeのURLを作成してweb.phpに渡す。
@csrf
なんだコレ
CSRF(Cross-Site Request Forgery)保護機能を有効にします。
なんとなく理解。
ランダムなトークンが一つ生成されて、その値が一致しないとサーバーを書き換えられないようにする仕組みらしい。
ログイン中であるアプリケーションに対して、クッキーが自動的に送信するブラウザの動作を悪用している攻撃を防ぐらしい。
クッキー情報が入ったとしてもトークンが一致しないため、送信を失敗させる仕組みとのこと。
もっと深い気がするが一旦、セキュリティといった形で進める。
<input type="hidden" name="thread_id" value="{{ $thread->id }}">
スレッドのIDを送信するよ。でもユーザーには見えないように隠すよ。
<textarea name="content" rows="3" required></textarea>
サーバーに送信する時のデータ名はcontent。
rows="3"はテキストエリア3行分。
requiredは入力必須項目。
<button type="submit">投稿</button>
</form>
@endsection
ボタンを押すとフォームデータをactionが指定したURLに送信。
ここまででユーザー側が見る画面を作成できた。
スレッド作成機能の実装
ルーティング設定
これはRoute::resouceで定義済み。
コントローラーにメソッドを追加
ThreadController.php
public function create()
{
return view('threads.create');
}
// 新しいスレッドをデータベースに保存する
public function store(Request $request)
{
// バリデーションを実行
$request->validate([
'title' => 'required|max:255', // タイトルは必須で最大255文字
]);
// データベースに保存
Thread::create([
'title' => $request->input('title'),
]);
// スレッド一覧ページにリダイレクト
return redirect()->route('threads.index')->with('success', 'スレッドを作成しました!');
}
public function create()
createメソッド
return view('threads.create');
viewのthreads.createを開く
public function store(Request $request)
Route::resourceで作成されたstoreで反応。
Request $request
フォームからのデータを$requestにいれる。
$request->validate
下記のルールに沿っているか確認。
'title' => 'required|max:255', // タイトルは必須で最大255文字
タイトルは必ず必要で文字数制限255まで
Thread::create()
Threadテーブルに新しいデータ入れますよ。
'title' => $request->input('title'),
]);
$requestの中のtitleをtitleにいれるよ
return redirect()->route('threads.index')->with('success', 'スレッドを作成しました!');
}
スレッドが作成されました。
と一緒にthreads.indexにリダイレクト。
ビューの作成
create.blade.phpを作る
@extends('layouts.app')
@section('content')
<h1>スレッドを作成</h1>
<!-- エラーメッセージの表示 -->
@if ($errors->any())
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- スレッド作成フォーム -->
<form method="POST" action="{{ route('threads.store') }}">
@csrf
<label for="title">スレッドタイトル</label>
<input type="text" name="title" id="title" value="{{ old('title') }}" required>
<button type="submit">作成</button>
</form>
@endsection
もうほとんど同じ繰り返しだ
ただ、エラーが出てくる文がある。
バリデーションエラーが発生した場合のものだった。
これの理由はPOST/Threadsに送信される。
入力ミスがあった場合エラー発生。
$errorsオブジェクトとしてテンプレートに渡される。
これを表示させるためのもの。
ModelsのThread.phpに
protected $fillable = ['title'];
を入れる。
これでtitle以外の追加はできなくなる。
これで一通り完成した。。。
が
全然動かなかった。
$slot
が定義されてないとひたすらでてGPTだとひたすらループの確認作業が始まったのであった。