Middlewareを使ってカテゴリーがない時は投稿を作成できないようにする【Laravel】

Laravel

laravelのmiddlewareについて実例を踏まえて詳しく知りたい!

こういった悩みを持っている方への記事です。

筆者は現在Laravelの学習中でして、学習中の気づきやまとめをブログを通してアウトプットしています。

自分自身が開発の最中にハマったところや理解しにくかったところを重点的にピックアップしてまとめています。

本記事では、ミドルウェアを使って、投稿を作成する際にカテゴリーがまだ作成されていない場合は、投稿を作成できないようにするようにしていきたいと思います。

5分で読めるので、Laravelのmiddlewareについて知りたい方は最後まで読んでみてください。

ミドルウェア(Middleware)とは?

ミドルウェアとは、リクエストを受け取った際に既存のコントローラーの処理の前後に割り込んで、独自の処理を追加する仕組みのことです。

PHP フレームワーク Laravel 入門 p.108

ミドルウェアには、前処理(Before Middleware)と後処理(After Middleware)の2種類があり、書き分けはMiddlewareクラスで行います。

カテゴリーがない時は投稿を作成できないようにする

実際に、私が学習した実例でmiddlewareの使い方を確認します。

①ミドルウェアを作成する

ターミナルで下記コマンドを打ち、middlewareクラスを作成。

php artisan middleware VerifyCategoryCount //(クラス名)

②作成したmiddlewareクラスに処理を書く

<?php

namespace App\Http\Middleware;

use Closure;
use App\Category;

class VerifyCotegoriesCount
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(Category::all()->count() === 0)
        {
          session()->flash('error', 'You need to add categories to be able to create a post.');
          return redirect('/home');
        }

        return $next($request);
    }
}

投稿を作成または修正する際、Categoryにデータが0だった場合、エラーが出るという処理。

count()とは?

コレクションのアイテム数を返すメソッド。

$collection = collect([1, 2, 3, 4]);

$collection->count();

// 4

sessionとは?

セッションは、サーバーとクライアント間の接続を維持し、個々のクライアントごとに各種のサービスや情報などを保持する技術。

PHP フレームワーク Laravel 入門 p.305

要するに、サイトに一時的に情報を保持してくれる機能です。(と私はアバウトに認識していますw)

なぜsessionが必要かというと、sessionが無いと、ページを移動した時にサーバー側では同じクライアントがアクセスしているかやクライアントが入力した情報を維持できないためです。

③Kernel.phpにミドルウェアを登録

作成したミドルウェアクラスはKernel.phpに登録しないと使用できません。

use App\Http\Middleware\VerifyCategoriesCount;

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'verifyCategoriesCount' => VerifyCategoriesCount::class, //<---これ
    ];

④Controllerにコンストラクタを記述

ミドルウェアはルートファイルの中で、コントローラーのルートに対して指定しますが、コントローラのコンストラクタの中でも指定ができます。

そうすることで、コントローラークラスの特定のメソッドに対してのみにミドルウェアの適用ができるメリットがあります。今回はその例になります。

public function __construct()
{
    $this->middleware('verifyCategoriesCount')->only(['create', 'store']); //onlyで対象のメソッドを制限
}

コンストラクタとは?

コンストラクタとはクラスからインスタンスを生成するとき(オブジェクトがnewによって作成されるとき)に自動的に呼び出されるメソッドです。

https://laraweb.net/surrounding/1472/

今回の例で言うと、コントローラーでの処理が実行されるたびに、コンストラクトに指定した、ミドルウェアクラス(verifyCategoriesCount)が実行されます。

以上で、これで投稿を作成する時に、カテゴリーを事前に作成していないと作成画面に進めないようにできました。

あとは、Viewでエラー文を表示します。

⑤Viewでエラー文を表示する

@if (session()->has('error'))
  <div class="alert alert-danger">
      {{ session()->get('error') }}
  </div>
@endif

まとめ

今回はミドルウェアを使った処理の一例を解説しました。

ミドルウェアはルーティングだけでなく、コンストラクタを使ってコントローラーで処理を実行できると実装の幅が広がりますね。

ご指摘等ございましたら、ご遠慮なくおっしゃっていただけますと幸いです。

参考サイト

Laravelのミドルウェアの実施順検証と小技 - Qiita
こんにちはみなさん 以前に@remore に「ミドルウェアってなんなんすかね?」って聞いたら、「ミドルウェアほど幅広く使われる言葉はそうないよね」と応えてきました。 一番初めに私が聞いたミドルウェアの意味は、アプリケーションが動く...
Laravel ミドルウェアの設定について - Qiita
内容 Laravelでのミドルウェア設定方法についての簡単なまとめ 具体的なミドルウェアの処理の実装に関しては記載しておりません。 環境 macOS Mojave 10.14.6 Laravel Framework ...
コレクション 6.x Laravel
これでセッションとクッキーの理解はスッキリ!(Laravel編) | アールエフェクト
セッションとクッキーの仕組みは文章として記述されているものはありますが実際のLaravelの値を見かけることはあまりありません。なんとなくはわかっているつもりかもしれませんがしっかりと理解できている人は少ないです。本文書を理解することでLaravelのセッションとクッキーについて疑問はかなりの部分解消されます。
HTTPセッション 6.x Laravel
コンストラクタ - Laravel学習帳
PHPのクラスでconstructを使う方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
初心者向けにPHPのクラスでconstructを使う方法について現役エンジニアが解説しています。PHPのクラスのconstructとはクラスのコンストラクタで、インスタンス生成時に最初に実行される関数です。
【Laravel】サービスコンテナとは?2つの強力な武器を持ったインスタンス化マシーン。簡単に解説。 - Qiita
はじめに サービスコンテナは、 Laravelのコアとなる機能で Laravelのめちゃくちゃ便利で魔法のような仕組みを 実現してくれているものです。 しかし、普段Laravelを使っていても 簡単なアプリケーションを作るうえ...
コントローラ 6.x Laravel