脱初心者備忘録

Laravelで定数の為だけにマスターテーブルを作るのをやめた件

今まで、selectやcheckbox、radioなどの選択肢に入れるワードの為だけにデーターベースにマスターテーブルを作ってました。コンフィグ専用のファイルを作るって人もいたと思います。

PHP8.1からEnumが使えるようになり、Laravelもその恩恵をあずかることに。無駄な作業が減ってスッキリします。

Appの中にEnumsディレクトリを作る

Appフォルダの中にEnumsという名前でフォルダを作ってください。

この中にファイルを作っていくことになります。

Enumsフォルダの中にファイルを作る

今回は、クーポンを配布するターゲットという前提で作ります。
適時、環境に合わせて、ファイルを作成してください。

まず、Enumsの中に、CouponTarget.phpという名称で、手動でファイルを作成します。

クラス名をつける(ファイル名=クラス名で作る)

新規様(BEGINNER)・常連様(REPEATER)・全員(ALL)という3つの選択肢があるとします。それをファイルの中に記載していきます。

3つの選択肢にそれぞれ数字を割り当てます。この辺はデータベースに登録するのと同じ感覚でOK。

各項目は大文字で記入します。

<?php

namespace App\Enums;

enum CouponTarget: int
{
    case BEGINNER = 1;
    case REPEATER = 2;
    case ALL = 3;

}

SELECTなりINPUTで呼び出したときの表示名をつける

このままでは、呼び出しても見た目は意味不明なので、各ケースに表示名を付けます。

ここで、PHP8から使える関数のmatch()を使用します。

<?php
$return_value = match (制約式) {
単一の条件式 => 返却式,
条件式1, 条件式2 => 返却式,
};
?>

https://www.php.net/manual/ja/control-structures.match.php
    public function label() : string
    {
        return match($this)
        {
            CouponTarget::BEGINNER => '新規様',
            CouponTarget::REPEATER => '常連様',
            CouponTarget::ALL => '全員',
        };
    }

これで、マッチしたらlabel名が返るというメソッドができました。

Bladeで呼び出すとき

例えばセレクト文で選択してほしいときは以下のように記載します。

<select name="target">
    <option value="">選択してください</option>
    @foreach (\App\Enums\CouponTarget::cases() as $target)
        <option value="{{ $target->value }}">{{ $target->label() }}</option>
    @endforeach
</select>

また、選択されたラベル名を表示するには下記のような書き方があります。

入力されたデータベースのcouponsテーブルでのカラム名がtargetとした場合。
ModelsのCoupon.phpがあるとして、Attributeを作っておくと便利。
$coupon->target_label でラベルを表示できる。

Class Coupon extends Model 
{
    public function getTargetLabelAttribute()
    {
        return CouponTarget::from($this->target)->label();
    }
}

便利なのでどんどん使いましょ。