postsテーブルに関するCRUD機能を実装します。
usersテーブルと重複する説明は簡略化します。
usersのCRUD機能を実装する
親記事
Laravel 5.7で基本的なCRUDを作る - Qiita
postsのモデル、コントローラを作る
PowerShell
# モデル生成
> php artisan make:model Post
# コントローラ生成
> php artisan make:controller PostController --resource
routes/web.php
// ルート追加
Route::resource('posts', 'PostController');
app/Http/Controllers/PostController.php
use Illuminate\Http\Request;
+use App\Post; // Postモデルをインポートする
class PostController extends Controller
{
一覧表示 (index)
コントローラ
投稿日の新しい順で記事を一覧表示します。
orderBy
メソッドよりもlatest
メソッドが便利です。
app/Http/Controllers/PostController.php
public function index()
{
// 1. 新しい順に取得できない
// $posts = Post::all();
// 2. 記述が長くなる
// $posts = Post::orderByDesc('created_at')->get();
// 3. latestメソッドがおすすめ
$posts = Post::latest()->get();
return view('posts.index', ['posts' => $posts]);
}
orderBy
, latest
はクエリビルダのメソッドですが、下記の通りEloquentモデルでも使えます。
Eloquentモデルはクエリビルダですから、クエリビルダで使用できる全メソッドを確認しておくべきでしょう。Eloquentクエリでどんなメソッドも使用できます。
readouble.com: Eloquent:利用の開始
クエリビルダの解説は下記を。
readouble.com: クエリビルダ
Laravel API: クエリビルダのクラス
なお、all
はModel
クラスのメソッドです。
Laravel API: Model::all
ビュー
usersと同じく、レイアウトとBootstrapを利用します。
resources/views/posts/index.blade.php
@php
$title = __('Posts');
@endphp
@extends('layouts.my')
@section('content')
<div class="container">
<h1>{{ $title }}</h1>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>{{ __('Title') }}</th>
<th>{{ __('Body') }}</th>
<th>{{ __('Created') }}</th>
<th>{{ __('Updated') }}</th>
</tr>
</thead>
<tbody>
@foreach ($posts as $post)
<tr>
<td>
<a href="{{ url('posts/'.$post->id) }}">{{ $post->title }}</a>
</td>
<td>{{ $post->body }}</td>
<td>{{ $post->created_at }}</td>
<td>{{ $post->updated_at }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
1件表示 (show)
コントローラ
app/Http/Controllers/PostController.php
/**
* Display the specified resource.
*
* @param \App\Post $post
* @return \Illuminate\Http\Response
*/
public function show(Post $post)
{
return view('posts.show', ['post' => $post]);
}
ビュー
usersと同じく、削除ボタン用のコンポーネントを利用します。
resources/views/posts/show.blade.php
@php
$title = $post->title;
@endphp
@extends('layouts.my')
@section('content')
<div class="container">
<h1 id="post-title">{{ $title }}</h1>
{{-- 編集・削除ボタン --}}
<div class="edit">
<a href="{{ url('posts/'.$post->id.'/edit') }}" class="btn btn-primary">
{{ __('Edit') }}
</a>
@component('components.btn-del')
@slot('table', 'posts')
@slot('id', $post->id)
@endcomponent
</div>
{{-- 記事内容 --}}
<dl class="row">
<dt class="col-md-2">{{ __('Created') }}:</dt>
<dd class="col-md-10">
<time itemprop="dateCreated" datetime="{{ $post->created_at }}">
{{ $post->created_at }}
</time>
</dd>
<dt class="col-md-2">{{ __('Updated') }}:</dt>
<dd class="col-md-10">
<time itemprop="dateModified" datetime="{{ $post->updated_at }}">
{{ $post->updated_at }}
</time>
</dd>
</dl>
<hr>
<div id="post-body">
{{ $post->body }}
</div>
</div>
@endsection
新規作成 (create, store)
コントローラ
app/Http/Controllers/PostController.php
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$post = new Post;
$post->title = $request->title;
$post->body = $request->body;
$post->save();
return redirect('posts/'.$post->id);
}
ビュー
resources/views/posts/create.blade.php
@php
$title = __('Create Post');
@endphp
@extends('layouts.my')
@section('content')
<div class="container">
<h1>{{ $title }}</h1>
<form action="{{ url('posts') }}" method="post">
@csrf
@method('POST')
<div class="form-group">
<label for="title">{{ __('Title') }}</label>
<input id="title" type="text" class="form-control" name="title" required autofocus>
</div>
<div class="form-group">
<label for="body">{{ __('Body') }}</label>
<textarea id="body" class="form-control" name="body" rows="8" required></textarea>
</div>
<button type="submit" name="submit" class="btn btn-primary">{{ __('Submit') }}</button>
</form>
</div>
@endsection
更新 (edit, update)
コントローラ
app/Http/Controllers/PostController.php
/**
* Show the form for editing the specified resource.
*
* @param \App\Post $post
* @return \Illuminate\Http\Response
*/
public function edit(Post $post)
{
return view('posts.edit', ['post' => $post]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Post $post
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
$post->title = $request->title;
$post->body = $request->body;
$post->save();
return redirect('posts/' . $post->id);
}
ビュー
resources/views/posts/edit.blade.php
@php
$title = __('Edit') . ': ' . $post->title;
@endphp
@extends('layouts.my')
@section('content')
<div class="container">
<h1>{{ $title }}</h1>
<form action="{{ url('posts/'.$post->id) }}" method="post">
@csrf
@method('PUT')
<div class="form-group">
<label for="title">{{ __('Title') }}</label>
<input id="title" type="text" class="form-control" name="title" value="{{ $post->title }}" required autofocus>
</div>
<div class="form-group">
<label for="body">{{ __('Body') }}</label>
<textarea id="body" class="form-control" name="body" rows="8" required>{{ $post->body }}</textarea>
</div>
<button type="submit" name="submit" class="btn btn-primary">{{ __('Submit') }}</button>
</form>
</div>
@endsection
削除 (destroy)
コントローラ
app/Http/Controllers/PostController.php
/**
* Remove the specified resource from storage.
*
* @param \App\Post $post
* @return \Illuminate\Http\Response
*/
public function destroy(Post $post)
{
$post->delete();
return redirect('posts');
}
ビュー
showのビューで、削除ボタン用のコンポーネントを既に配置しています。