一覧・登録・編集・削除を実装する
設計したメモ投稿アプリを、リソースコントローラ・ビュー・認証・認可を組み合わせて実際に作り上げます。
前の単元の設計をもとに、メモ投稿アプリを実装します。これまでの章の総まとめです。一気に見えますが、1つ1つはすべて既に学んだことです。落ち着いて進めましょう。
1. 下準備(モデル・コントローラなどを作る)
必要なファイルをまとめて作ります。
php artisan make:model Post -mcr
-mcr は「migration(マイグレーション)・controller(コントローラ)・resource(7メソッド入り)」をまとめて作るオプションです。
マイグレーション(第4章)に、前の単元で設計した列を書いて実行します。
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('title');
$table->text('body');
$table->timestamps();
});
php artisan migrate
Post モデルに $fillable を設定します(第5章)。
class Post extends Model
{
protected $fillable = ['title', 'body'];
}
2. ルート(ログイン必須にする)
routes/web.php に、ログイン必須のリソースルートを書きます(第7章)。
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class)->middleware('auth');
3. コントローラ
app/Http/Controllers/PostController.php を実装します。各メソッドの中身は、これまで学んだ内容そのものです。認可で Gate を使うので、ファイル先頭に use Illuminate\Support\Facades\Gate; を追加しておきます(第7章を参照)。
public function index()
{
// 自分のメモだけを新しい順で取得
$posts = Post::where('user_id', auth()->id())->latest()->get();
return view('posts.index', ['posts' => $posts]);
}
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'max:255'],
'body' => ['required'],
]);
// 投稿者=ログイン中の人として保存
$request->user()->posts()->create($validated);
return redirect('/posts');
}
public function edit(Post $post)
{
Gate::authorize('update', $post); // 本人だけ(第7章)
return view('posts.edit', ['post' => $post]);
}
public function update(Request $request, Post $post)
{
Gate::authorize('update', $post);
$validated = $request->validate([
'title' => ['required', 'max:255'],
'body' => ['required'],
]);
$post->update($validated);
return redirect('/posts');
}
public function destroy(Post $post)
{
Gate::authorize('delete', $post);
$post->delete();
return redirect('/posts');
}
$request->user()->posts()->create(...)は、リレーション(第5章)を使った書き方で、user_idが自動でログイン中の人になります。
store で使うリレーションのため、User モデルに posts() を、Post モデルに user() を書いておきます(第5章)。また編集・削除の本人チェックのため、ポリシー(第7章)も用意します。
php artisan make:policy PostPolicy --model=Post
// PostPolicy.php
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
4. 画面(Blade)
一覧 resources/views/posts/index.blade.php:
<a href="/posts/create">新規メモ</a>
@forelse ($posts as $post)
<div>
<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>
<a href="/posts/{{ $post->id }}/edit">編集</a>
<form action="/posts/{{ $post->id }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">削除</button>
</form>
</div>
@empty
<p>まだメモがありません。</p>
@endforelse
新規作成 resources/views/posts/create.blade.php:
<form action="/posts" method="POST">
@csrf
<input type="text" name="title" value="{{ old('title') }}">
@error('title') <p style="color:red">{{ $message }}</p> @enderror
<textarea name="body">{{ old('body') }}</textarea>
@error('body') <p style="color:red">{{ $message }}</p> @enderror
<button type="submit">保存</button>
</form>
@method('DELETE') とは
HTMLのフォームは GET と POST しか送れません。削除(DELETE)や更新(PUT)をしたいときは、@method('DELETE') を書いて Laravel に「本当はDELETEです」と伝えます。これも @csrf とセットで覚えておきましょう。
編集画面(
edit.blade.php)は、createとほぼ同じフォームに@method('PUT')を足し、valueに既存の値({{ old('title', $post->title) }})を入れれば作れます。
5. 動作確認
php artisan serve で起動し、ログインしてから /posts を開きます。新規作成・編集・削除ができ、他人のメモには編集・削除ボタンが効かない(ポリシーで弾かれる)ことを確認できれば完成です。
まとめ
make:model Post -mcrで必要なファイルを一括生成。- ルートは
Route::resource(...)->middleware('auth')でCRUD+ログイン必須。 - コントローラの各メソッドは、これまで学んだ取得・保存・更新・削除・認可の組み合わせ。
- フォームの削除・更新は
@method('DELETE')/@method('PUT')を使う。 - これで第8章=アプリ作りの一周が完成です。最終章では、作ったアプリをインターネットに公開します。