laravel5.6

Laravel5.6: postsのCRUD機能を実装する

postsテーブルに関するCRUD機能を実装します。
usersテーブルと重複する説明は簡略化します。
:link: usersのCRUD機能を実装する

親記事

Laravel 5.6で基本的な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)

001.png

コントローラ

投稿日の新しい順で記事を一覧表示します。
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クエリでどんなメソッドも使用できます。

:link: Eloquent:利用の開始

クエリビルダの解説は下記を。
:link: クエリビルダ (公式解説)
:link: クエリビルダのメソッドの一覧 (APIリファレンス)

なお、allModelクラスのメソッドです。
:link: Model::all (APIリファレンス)

ビュー

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)

002.png

コントローラ

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)

003.png

コントローラ

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-success">{{ __('Submit') }}</button>
    </form>
</div>
@endsection

更新 (edit, update)

004.png

コントローラ

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-success">{{ __('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のビューで、削除ボタン用のコンポーネントを既に配置しています。