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

  • 0
    Like
  • 0
    Comment

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

    親記事

    Laravel 5.5で基本的な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')
    <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>
    @endsection
    

    show

    002.png

    コントローラ

    app/Http/Controllers/PostController.php
        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')
    <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>
    @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')
    <h1>{{ $title }}</h1>
    <form action="{{ url('posts') }}" method="post">
        {{ csrf_field() }}
        {{ method_field('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>
    @endsection
    

    edit, update

    004.png

    コントローラ

    app/Http/Controllers/PostController.php
        public function edit(Post $post)
        {
            return view('posts.edit', ['post' => $post]);
        }
    
        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')
    <h1>{{ $title }}</h1>
    <form action="{{ url('posts/'.$post->id) }}" method="post">
        {{ csrf_field() }}
        {{ method_field('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>
    @endsection
    

    destroy

    コントローラ

    app/Http/Controllers/PostController.php
        public function destroy(Post $post)
        {
            $post->delete();
            return redirect('posts');
        }
    

    ビュー

    showのビューで、削除ボタン用のコンポーネントを既に配置しています。