副業におすすめなサイトを見る→

Laravel9ニュースサイト⑨記事の編集・更新【Laravel9×TailwindCSS】

アプリリリースのお知らせ

予定を探すアプリyoteipickerをリリースしました。

アプリの利用用途:暇だから何か予定入れたいけど今週の土日は何しようかな〜?ってときに使えるアプリです。

前回までの記事

  1. ニュースサイト概要
  2. 環境構築
  3. 総合トップ画面の作成
  4. マイページの作成
  5. ユーザー新規登録・ログイン・ログアウト
  6. マイページの投稿リスト
  7. 記事投稿
  8. 記事の詳細

開発環境

環境バージョン
MacBook AirMonterey 12.2.1
Docker20.10.7
PHP8.1
composer2.2.9
Laravel9.5.1
apache2.4
MySQL8.0
phpmyadmin
npm8.5
node12.22.11
React17
TailwindCSS3
Laravel/breezeログイン認証機能で使用
※Laravel8以降の場合に使用可。
Laravel6や7系はreact –authとか使います。

開発+α

◆dockerコンテナの情報を確認する
→docker ps

◆dockerのphpコンテナに入る
→docker exec -it コンテナIDまたはNAMES bash

◆var/www# はphpコンテナ内を表します。php artisanやnpm run devなどはphpコンテナ内で実行しましょう。

◆tailwindcssでスタイルを変更する前に
→npm run watchを実行していると開発が楽。
※ある程度スタイルが整ったら、npm run devでビルドしましょう。
すると、不要なcssを削除してくれるのでcssファイルが軽くなります。

◆スタイルが適用されないときは….
npm run devで一旦ビルドしてみるか、スーパーリロードでキャッシュの削除をしてみましょう。

この記事でやること
  • 記事の編集画面を作成する
  • 記事の更新処理を作る

最終的なゴール

  • 記事のステータスが下書き保存の場合
  • 記事のステータスが公開の場合
  • 記事のステータスが予約公開の場合

※予約公開日や予約公開時間については、予約公開の章で実装するので、今はなくても問題なし。

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

Contents

記事の編集画面を作成する

完成図

記事の編集や更新処理を実装する流れは、投稿や詳細処理を同じような流れです。

STEP
ルーティングでパスを追加する
STEP
コントローラーにアクションを追加する

記事の編集画面のルーティングを追加する

記事の編集画面のルーティングを追加します。

/post/edit/1で記事ごとの編集画面にアクセスするようにしてます。

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TopController;
use App\Http\Controllers\User\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';

// 総合トップ
Route::get('/', [TopController::class, 'top'])
    ->name('top');

// 総合トップ記事詳細画面
Route::get('/article/{post_id}', [TopController::class, 'articleShow'])
    ->name('top.article.show');

// 総合トップカテゴリーごとの記事一覧
Route::get('/article/category/{category_id}', [TopController::class, 'articleCategory'])
    ->name('top.article.category');

// マイページトップ・投稿
Route::get('/user/{id}/index', [PostController::class, 'index'])
    ->name('user.index');

// 投稿登録画面
Route::get('/post/create', [PostController::class, 'create'])
    ->name('post.create');

// 投稿登録処理
Route::post('/post/store', [PostController::class, 'store'])
    ->name('post.store');

// 投稿詳細
Route::get('/post/show/{post_id}', [PostController::class, 'show'])
    ->name('post.show');

// 記事編集
Route::get('/post/edit/{post_id}', [PostController::class, 'edit'])
    ->name('post.edit');

Postコントローラーにeditアクションを追加する

Postコントローラーにeditアクションを追加しましょう。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    private $post;
    private $category;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
    }

    /**
     * 投稿リスト
     *
     * @param int $id ユーザーID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function index(int $id)
    {
        // ユーザーIDと一致する投稿データを取得
        $posts = $this->post->getAllPostsByUserId($id);
        return view('user.list.index', compact(
            'posts',
        ));
    }

    /**
     * 記事投稿画面
     *
     * @return Response src/resources/views/user/list/create.blade.phpを表示
     */
    public function create()
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        return view('user.list.create', compact(
            'categories',
        ));
    }

    /**
     * 記事投稿処理
     *
     * @param string $request リクエストデータ
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function store(PostRequest $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->insertPostToSaveDraft($user_id, $request);
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->insertPostToRelease($user_id, $request);
                break;
            // 予約公開クリック時の処理
            case $request->has('reservation_release'):
                $this->post->insertPostToReservationRelease($user_id, $request);
                break;
            // 上記以外の処理
            default:
                $this->post->insertPostToSaveDraft($user_id, $request);
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 記事詳細
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/show.blade.phpを表示
     */
    public function show($post_id) {
        // リクエストされた投稿IDをもとにpostsテーブルから一意のデータを取得
        $showPostData = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.show', compact(
            'showPostData',
        ));
    }

    /**
     * 記事編集
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/edit.blade.phpを表示
     */
    public function edit($post_id)
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.edit', compact(
            'categories',
            'post',
        ));
    }
}

マイページの投稿リストのEditをクリックした時に、編集ページに遷移するようにします。(今はまだ編集画面を作成していないのでエラー出る)

記事の編集画面は、/post/edit/{post_id}でアクセスできるので、[‘post_id’ => $post->id]と書くことで投稿IDを{post_id}の部分に渡せます。

参考:Laravel9公式ルーティング_名前付きルートのURL生成を参照

<td class="px-5 py-5 mr-5 border-b border-gray-200 bg-white text-sm">
    <a class="mr-3 text-blue-700 whitespace-no-wrap underline" href="{{ route('post.edit', ['post_id' => $post->id]) }}">
        Edit
    </a>
    <a class="ml-5 underline text-red-700 whitespace-no-wrap" href="#">
        delete
    </a>
</td>

記事の編集画面を作成する

編集画面を作成しましょう。新規で/resources/views/user/list/edit.blade.phpを作成します。

一旦、コードの全文を書き、その後に解説します。

{{-- src/resources/views/layouts/common.blade.php継承 --}}
@extends('layouts.common')

@include('user.parts.sidebar_user')
@section('content')
@if ($post->publish_flg === 0)
    <div class="bg-blue-200 text-center text-blue-700 font-bold">ステータス:下書き保存</div>
@elseif ($post->publish_flg === 1)
    <div class="bg-green-200 text-center text-green-700 font-bold">ステータス:公開中</div>
@elseif ($post->publish_flg === 2)
    <div class="bg-amber-200 text-center text-amber-700 font-bold">ステータス:予約公開</div>
@else
@endif
{{-- formアクションは、この後updateアクションを追加する際に設定するので今は空欄でOK --}}
<form action="" method="POST" class="p-5">
@csrf
    @if ($errors->any())
        <div class="flex shadow-lg rounded-sm">
            <div class="bg-red-600 py-4 px-6 rounded-l-lg flex items-center">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="fill-current text-white" width="20" height="20">
                    <path fill-rule="evenodd" d="M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path>
                </svg>
            </div>
            <div class="px-4 py-6 bg-red-50 rounded-r-lg justify-between items-center w-full border border-l-transparent border-red-50">
                <div class="text-red-600 text-md font-bold">エラー!</div>
                <ul>
                    @foreach ($errors->all() as $error)
                        <li  class="text-sm text-red-500">{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        </div>
    @endif
    <div class="flex mt-6 mr-12">
        <div class="m-auto">
            <select name="category" class="block w-64 text-gray-700 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500">
                <option value="">カテゴリーを選択</option>
                @foreach ($categories as $category)
                    {{-- バリデーションエラー発生時、直前で選択した値を選択した状態にする --}}
                    @if (old('category'))
                        <option value="{{ $category->id }}" @selected(old('category') == $category->id)>{{ $category->category_name }}</option>
                    {{-- 編集画面で、DBに登録しているデータを選択状態にする --}}
                    @elseif ($category->id == $post->category_id)
                        <option value="{{ $category->id }}" @selected($post->category_id)>{{ $category->category_name }}</option>
                    {{-- 上記以外の場合は、選択状態にしない(記事新規作成の初期状態など) --}}
                    @else
                        <option value="{{ $category->id }}">{{ $category->category_name }}</option>
                    @endif
                @endforeach
            </select>
        </div>
        <div>
            {{-- ステータスによって、表示するボタンや文言を変更 --}}
            @if ($post->publish_flg === 0)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button type="submit" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @elseif ($post->publish_flg === 1)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
            @elseif ($post->publish_flg === 2)
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書きに戻す</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">今すぐ公開</button>
                <button type="submit" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約日時を変更</button>
            @else
                <button type="submit" name="save_draft" class="px-4 py-2 text-white text-lg transition-colors duration-200 transform bg-blue-500 rounded-md hover:bg-blue-400">下書き保存</button>
                <button type="submit" name="release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-green-500 rounded-md hover:bg-green-400">更新して公開</button>
                <button type="submit" name="reservation_release" class="px-4 py-2 ml-8 text-white text-lg transition-colors duration-200 transform bg-amber-500 rounded-md hover:bg-amber-400">予約公開</button>
            @endif
        </div>
    </div>
    <div class="w-full mt-4">
        <input type="text" name="title" class="block w-full text-3xl font-bold border-none outline-none" placeholder="タイトルを追加" value="{{ old('title', $post->title) }}"/>
    </div>
    <div class="w-full mt-4">
        <textarea name="body" class="block w-full h-40 px-4 py-2 border-none resize-none text-gray-700 bg-white border rounded-md focus:outline-none focus:ring" placeholder="記事の内容を書いてください">{{ old('body', $post->body) }}</textarea>
    </div>
</form>
@endsection

①記事のステータスについて

記事のステータスは下書き保存(publish_flg=0)、公開(publish_flg=1)、予約公開(publish_flg=2)なので、postsテーブルにある記事のステータスによって条件分岐させています。

なので、記事のステータスに応じて表示するボタンや文言などを変えていますが、55-70行目あたりも同じく、publish_flgによって条件分岐させています。

@if ($post->publish_flg === 0)
    <div class="bg-blue-200 text-center text-blue-700 font-bold">ステータス:下書き保存</div>
@elseif ($post->publish_flg === 1)
    <div class="bg-green-200 text-center text-green-700 font-bold">ステータス:公開中</div>
@elseif ($post->publish_flg === 2)
    <div class="bg-amber-200 text-center text-amber-700 font-bold">ステータス:予約公開</div>
@else
    <div></div>
@endif

②カテゴリーのプルダウンについて

→ここは記事投稿でもold関数などを使ったので説明は省きます。

ただ、DBに登録してあるデータを参照して、編集画面遷移時にプルダウンを選択しておくところは新しいですね。

@elseif ($category->id == $post->category_id)
  <option value="{{ $category->id }}" @selected($post->category_id)>{{ $category->category_name }}</option>

やってることは単純で、選択した値(category->id)とDBに登録してある値(post->category_id)が一致したら、DBに登録してある値を選択状態にするだけです。

記事の更新機能を実装する

記事の編集画面ができたので、今度は記事の更新を実装していきましょう。

完成図

Editをクリックすると、記事の編集画面にいく。※最終更新日時や操作がEditとTrashになっていますが、今は日付とdeleteになっていると思うので、今はスルーで!後でやりまぁす。

記事の編集をし、いずれかのボタンをクリック。

編集した記事のDBデータを更新する。

記事の更新ルーティングを追加する

記事の更新をするためのルーティングを追加します。

更新処理は、記事の投稿(store)みたいに、postアクションになります。

参考:Laravel9公式ルーティング

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TopController;
use App\Http\Controllers\User\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';

// 総合トップ
Route::get('/', [TopController::class, 'top'])
    ->name('top');

// 総合トップ記事詳細画面
Route::get('/article/{post_id}', [TopController::class, 'articleShow'])
    ->name('top.article.show');

// 総合トップカテゴリーごとの記事一覧
Route::get('/article/category/{category_id}', [TopController::class, 'articleCategory'])
    ->name('top.article.category');

// マイページトップ・投稿
Route::get('/user/{id}/index', [PostController::class, 'index'])
    ->name('user.index');

// 投稿登録画面
Route::get('/post/create', [PostController::class, 'create'])
    ->name('post.create');

// 投稿登録処理
Route::post('/post/store', [PostController::class, 'store'])
    ->name('post.store');

// 投稿詳細
Route::get('/post/show/{post_id}', [PostController::class, 'show'])
    ->name('post.show');

// 記事編集
Route::get('/post/edit/{post_id}', [PostController::class, 'edit'])
    ->name('post.edit');

// 記事更新
Route::post('/post/edit/{post_id}', [PostController::class, 'update'])
    ->name('post.update');

Postコントローラーにupdateアクションを追加する

Postコントローラーにupdateアクションを追加します。※ほぼ記事の登録と同じような処理です。

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\Post;
use App\Models\Category;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    private $post;
    private $category;

    public function __construct()
    {
        $this->post = new Post();
        $this->category = new Category();
    }

    /**
     * 投稿リスト
     *
     * @param int $id ユーザーID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function index(int $id)
    {
        // ユーザーIDと一致する投稿データを取得
        $posts = $this->post->getAllPostsByUserId($id);
        return view('user.list.index', compact(
            'posts',
        ));
    }

    /**
     * 記事投稿画面
     *
     * @return Response src/resources/views/user/list/create.blade.phpを表示
     */
    public function create()
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        return view('user.list.create', compact(
            'categories',
        ));
    }

    /**
     * 記事投稿処理
     *
     * @param string $request リクエストデータ
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function store(PostRequest $request)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->insertPostToSaveDraft($user_id, $request);
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->insertPostToRelease($user_id, $request);
                break;
            // 予約公開クリック時の処理
            case $request->has('reservation_release'):
                $this->post->insertPostToReservationRelease($user_id, $request);
                break;
            // 上記以外の処理
            default:
                $this->post->insertPostToSaveDraft($user_id, $request);
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }

    /**
     * 記事詳細
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/show.blade.phpを表示
     */
    public function show($post_id) {
        // リクエストされた投稿IDをもとにpostsテーブルから一意のデータを取得
        $showPostData = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.show', compact(
            'showPostData',
        ));
    }

    /**
     * 記事編集
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/edit.blade.phpを表示
     */
    public function edit($post_id)
    {
        // カテゴリーデータを全件取得
        $categories = $this->category->getAllCategories();
        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);
        return view('user.list.edit', compact(
            'categories',
            'post',
        ));
    }

    /**
     * 記事の更新
     *
     * @param int $post_id 投稿ID
     * @return Response src/resources/views/user/list/index.blade.phpを表示
     */
    public function update(PostRequest $request, $post_id)
    {
        // ログインしているユーザー情報を取得
        $user = Auth::user();
        // ログインユーザー情報からユーザーIDを取得
        $user_id = $user->id;

        // 投稿IDをもとに特定の投稿データを取得
        $post = $this->post->feachPostDateByPostId($post_id);

        switch (true) {
            // 下書き保存クリック時の処理
            case $request->has('save_draft'):
                $this->post->updatePostToSaveDraft($request, $post);
                break;
            // 公開クリック時の処理
            case $request->has('release'):
                $this->post->updatePostToRelease($request, $post);
                break;
            // 予約公開クリック時の処理
            case $request->has('reservation_release'):
                $this->post->updatePostToReservationRelease($request, $post);
                break;
            // 上記以外の処理
            default:
                $this->post->updatePostToSaveDraft($request, $post);
                break;
        }

        return to_route('user.index', ['id' => $user_id]);
    }
}

updateアクションでは、updatePostToSaveDraft,updatePostToRelease,updatePostToReservationReleaseを定義したので、Postモデルに処理を追加しましょう。

  • updatePostToSaveDraft→編集画面で下書き保存をクリックし、DBを更新する処理
  • updatePostToRelease→編集画面で公開をクリックし、DBを更新する処理
  • updatePostToReservationRelease→編集画面で予約公開をクリックし、DBを更新する処理

PostモデルにDB更新処理をかく

Postモデルに先ほどの3つの処理を書いていきます。

ちなみに、DBの更新処理はfillとsaveを使ってデータを更新できます。

参考:Laravel9公式Eloquent

過去記事:LaravelでTodoアプリを作成する④

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use App\Models\Category;
use Illuminate\Support\Carbon;

/**
 * 投稿モデル
 */
class Post extends Model
{
    /**
     * モデルに関連付けるテーブル
     *
     * @var string
     */
    protected $table = 'posts';

    /**
     * 複数代入可能な属性
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'category_id',
        'title',
        'body',
        'publish_flg',
        'view_counter',
        'favorite_counter',
        'delete_flg',
        'created_at',
        'updated_at'
    ];

    /**
     * Userモデルとリレーション
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Categoryモデルとリレーション
     */
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    /**
     * 投稿データを全て取得し、最新更新日時順にソート
     */
    public function getPostsSortByLatestUpdate()
    {
        $result = $this->where('publish_flg', 1)
                       ->orderBy('updated_at', 'DESC')
                       ->with('user')
                       ->with('category')
                       ->get();
        return $result;
    }

    /**
     * カテゴリーごとの記事を全て取得
     *
     * @param int $category_id カテゴリーID
     */
    public function getPostByCategoryId($category_id)
    {
        $result = $this->where('category_id', $category_id)
                       ->get();
        return $result;
    }

    /**
     * ユーザーIDに紐づいた投稿リストを全て取得する
     *
     * @param int $user_id ユーザーID
     * @return Post
     */
    public function getAllPostsByUserId($user_id)
    {
        $result = $this->where('user_id', $user_id)->with('category')->get();
        return $result;
    }

    /**
     * 下書き保存=>publish_flg=0
     * リクエストされたデータをpostsテーブルにinsertする
     *
     * @param int $user_id ログインユーザーID
     * @param array $request リクエストデータ
     * @return object $result App\Models\Post
     */
    public function insertPostToSaveDraft($user_id, $request)
    {
        $result = $this->create([
            'user_id'          => $user_id,
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 0,
            'view_counter'     => 0,
            'favorite_counter' => 0,
            'delete_flg'       => 0,
        ]);
        return $result;
    }

    /**
     * 公開=>publish_flg=1
     * リクエストされたデータをpostsテーブルにinsertする
     *
     * @param int $user_id ログインユーザーID
     * @param array $request リクエストデータ
     * @return object $result App\Models\Post
     */
    public function insertPostToRelease($user_id, $request)
    {
        $result = $this->create([
            'user_id'          => $user_id,
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 1,
            'view_counter'     => 0,
            'favorite_counter' => 0,
            'delete_flg'       => 0,
        ]);
        return $result;
    }

    /**
     * 予約公開=>publish_flg=2
     * リクエストされたデータをpostsテーブルにinsertする
     *
     * @param int $user_id ログインユーザーID
     * @param array $request リクエストデータ
     * @return object $result App\Models\Post
     */
    public function insertPostToReservationRelease($user_id, $request)
    {
        $result = $this->create([
            'user_id'          => $user_id,
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 2,
            'view_counter'     => 0,
            'favorite_counter' => 0,
            'delete_flg'       => 0,
        ]);
        return $result;
    }

    /**
     * 投稿IDをもとにpostsテーブルから一意の投稿データを取得
     *
     * @param int $post_id 投稿ID
     * @return object $result App\Models\Post
     */
    public function feachPostDateByPostId($post_id)
    {
        $result = $this->find($post_id);
        return $result;
    }

    /**
     * 記事の更新処理
     * 下書き保存=>publish_flg=0
     * リクエストされたデータをもとにpostデータを更新する
     *
     * @param array $post 投稿データ
     * @return object $result App\Models\Post
     */
    public function updatePostToSaveDraft($request, $post)
    {
        $result = $post->fill([
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 0,
        ]);

        $result->save();

        return $result;
    }

    /**
     * 記事の更新処理
     * 公開=>publish_flg=1
     * リクエストされたデータをもとにpostデータを更新する
     *
     * @param array $post 投稿データ
     * @return object $result App\Models\Post
     */
    public function updatePostToRelease($request, $post)
    {
        $result = $post->fill([
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 1,
        ]);

        $result->save();

        return $result;
    }

    /**
     * 記事の更新処理
     * 公開予約=>publish_flg=0
     * リクエストされたデータをもとにpostデータを更新する
     *
     * @param array $post 投稿データ
     * @return object $result App\Models\Post
     */
    public function updatePostToReservationRelease($request, $post)
    {
        $result = $post->fill([
            'category_id'      => $request->category,
            'title'            => $request->title,
            'body'             => $request->body,
            'publish_flg'      => 2,
        ]);

        $result->save();

        return $result;
    }
}

最後に先ほど編集画面でformのアクション先を設定していないため、こちらを追加します。

<form action="{{ route('post.update', ['post_id' => $post->id]) }}" method="POST" class="p-5">

これで、マイページの投稿リストの記事一覧から、Editをクリック→適当に編集してボタンを押す→投稿リストにリダイレクトされて記事が更新されている流れが作れました。

実際にDBも確認してみると…

更新して公開をクリックすると、一覧画面にリダイレクト

postsテーブルの投稿IDが71のデータが更新されていることが確認できた。

ちょっとイケてない箇所を修正する

投稿リストの記事一覧で、現状は日付が記事の作成日時となっているため、これを最終更新日時に変更します。

↓※deleteの部分がTrashになっていますが、これは後ほどやるんでスルーでお願いしやす。

{{-- src/resources/views/layouts/common.blade.php継承 --}}
@extends('layouts.common')

@include('user.parts.sidebar_user')
@section('content')
<div class="h-screen overflow-y-scroll">
    <div class="px-4 sm:px-4">
        <div class="flex justify-between">
            <div class="text-2xl font-bold pt-7">投稿</div>
            <div class="pt-4">
                <a href="{{ route('post.create') }}">
                    <button class="bg-blue-500 text-white px-4 py-2 rounded-md text-1xl font-medium hover:bg-blue-700 transition duration-300">
                        新規追加
                    </button>
                </a>
            </div>
        </div>
        <div class="py-4">
            <div class="overflow-x-auto">
                <div class="inline-block min-w-full shadow rounded-lg overflow-hidden">
                    <table class="min-w-full leading-normal">
                        <thead>
                            <tr>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    タイトル
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    投稿ID
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    カテゴリー
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    ステータス
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    最終更新日時
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-left text-sm uppercase font-normal">
                                    操作
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    PV数
                                </th>
                                <th scope="col" class="px-5 py-3 bg-white  border-b border-gray-200 text-gray-800  text-center text-sm uppercase font-normal">
                                    お気に入り数
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach ($posts as $post)
                            <tr>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm w-40">
                                    <a href="{{ route('post.show', ['post_id' => $post->id]) }}" class="hover:underline">
                                        <p class="text-left text-gray-900 whitespace-no-wrap">
                                            {{ $post->title }}
                                        </p>
                                    </a>
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
                                    <p class="text-center text-gray-900 whitespace-no-wrap">
                                        {{ $post->id }}
                                    </p>
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm text-center">
                                    <span class="relative inline-block px-3 py-1 font-semibold text-white leading-tight">
                                        <span aria-hidden="true" class="absolute inset-0 bg-green-500 rounded-full">
                                        </span>
                                        <span class="relative">
                                            @if (isset($post->category_id))
                                                {{ $post->category->category_name }}
                                            @else
                                                カテゴリーなし
                                            @endif
                                        </span>
                                    </span>
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm text-center">
                                    @if ($post->publish_flg === 0)
                                        <span class="relative inline-block px-3 py-1 font-semibold text-blue-900 leading-tight">
                                            <span aria-hidden="true" class="absolute inset-0 bg-blue-200 opacity-50 rounded-full">
                                            </span>
                                            <span class="relative">
                                                下書き保存
                                            </span>
                                        </span>
                                    @elseif ($post->publish_flg === 1)
                                        <span class="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight">
                                            <span aria-hidden="true" class="absolute inset-0 bg-green-200 opacity-50 rounded-full">
                                            </span>
                                            <span class="relative">公開済み</span>
                                        </span>
                                    @elseif ($post->publish_flg === 2)
                                        <span class="relative inline-block px-3 py-1 font-semibold text-amber-900 leading-tight">
                                            <span aria-hidden="true" class="absolute inset-0 bg-amber-200 opacity-50 rounded-full">
                                            </span>
                                            <span class="relative">予約公開</span>
                                        </span>
                                    @else
                                        <span class="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight">
                                            <span aria-hidden="true" class="absolute inset-0 bg-green-200 opacity-50 rounded-full">
                                            </span>
                                            <span class="relative">下書き保存</span>
                                        </span>
                                    @endif
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
                                    <p class="text-center text-gray-900 whitespace-no-wrap">
                                        {{ $post->updated_at }}
                                    </p>
                                </td>
                                <td class="px-5 py-5 mr-5 border-b border-gray-200 bg-white text-sm">
                                    <a class="mr-3 text-blue-700 whitespace-no-wrap underline" href="{{ route('post.edit', ['post_id' => $post->id]) }}">
                                        Edit
                                    </a>
                                    <a class="ml-5 underline text-red-700 whitespace-no-wrap" href="#">
                                        delete
                                    </a>
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
                                    <p class="text-center text-gray-900 whitespace-no-wrap">
                                        {{ $post->view_counter }}
                                    </p>
                                </td>
                                <td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
                                    <p class="text-center text-gray-900 whitespace-no-wrap">
                                        {{ $post->favorite_counter }}
                                    </p>
                                </td>
                            </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

投稿リストの記事を取得するロジックにも更新日時順にソートを追加しておきましょう。

    /**
     * ユーザーIDに紐づいた投稿リストを全て取得する
     *
     * @param int $user_id ユーザーID
     * @return Post
     */
    public function getAllPostsByUserId($user_id)
    {
        $result = $this->where('user_id', $user_id)
                       ->with('category')
                       ->orderBy('updated_at', 'DESC')
                       ->get();
        return $result;
    }

イケてる感じになりました。

本日はこれにて御免。

次回は、記事のゴミ箱・削除機能を実装していきますわよ。

>>>記事のゴミ箱・削除へ進む

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

スキルを売り買いするならココナラ

コメント

コメントする

CAPTCHA


Contents
閉じる