カテゴリー: BackEnd

laravel-enumを使ってみたら快適だった

はじめに

こんにちは。Laravelでenumを使いたい時、PHPやLaravel本体ではサポートされていないのでComposer経由でパッケージを入れることになります。
今はbensampo/laravel-enumを使っており、とりあえず不自由ない感じなので、紹介しようと思います。

enumについて

列挙型 – Wikipedia

railsで初めてenumを知ったのですが、C言語の時点で既にあったのですね。
私は「限られた値しか持てないデータ型」と認識してます。

例えば注文情報テーブルに支払方法を保存する時、データベースのordersテーブルにpayment_typeカラムを持たせるとします。
card, transfer, cashなど支払方法名だけがorders.payment_typeに入るようにしつつ、表示時は「クレジットカード」や「銀行振込」といった文字列で扱いたい…なんてケースはよくあると思いますが、こういう場合に便利です。

環境

  • PHP 7.3.3
  • Laravel 5.8
  • laravel-enum 1.9

導入

composerコマンドでさくっとインストール完了です。

$ composer require bensampo/laravel-enum

Using version ^1.19 for bensampo/laravel-enum
./composer.json has been created
Loading composer repositories with package information
...
...
...
Writing lock file
Generating autoload files

enumクラス

生成

マイグレーションはenumクラスの後に作った方が(多分)効率が良いので、まずはenumクラスを生成します。

$ php artisan make:enum PaymentType
Enum created successfully.

なおデフォルトではapp/Enumsディレクトリが生成され、その中にPHPファイルが自動生成されます。ディレクトリを切り分けたい場合、例えばapp/Enums/Orderに作りたいのであればOrder/PaymentTypeとなります。
このパラメータ、app/Enumsを起点とした相対パスとして扱われるので、例えば$ php artisan make:enum ../Models/Enums/TestEnumと記述すれば、app/Models/EnumsTestEnum.phpが生成されます。
ディレクトリ構造はプロジェクトによって様々だと思いますので、お好みで。

enumクラス編集

日本語化

続いて公式の方法に従ってresources/lang/ja/enums.phpを作成し、以下のように記述します。フレームワークのlocale設定に従ったenums.phpを読みに行きますので、config/app.phplocaleを日本(ja)に設定しておきましょう。

 'ja',

    // 中略
];
 [
        PaymentType::CREDIT_CARD => 'クレジットカード',
        PaymentType::TRANSFER => '銀行振込',
        PaymentType::CASH => '現金',
    ],
];

マイグレーション

生成

ordersテーブルにpayment_typeというenum型のカラムを追加します。

$ php artisan make:migration add_column_payment_type --table=orders
Created Migration: 2019_05_**_******_add_column_payment_type

編集

$table->enum()Laravel 5.8から使用できます。直接指定できるのはいいですね。
また「マイグレーションはクラス作成の後で」と前述したのは、enum型カラムの定義にenumクラスの値を適用できるためです。もちろん配列をべた書きしてもいいのですが、この方がすっきり分かりやすいかなと。

enum('payment_type', PaymentType::getValues())
                ->default(PaymentType::CREDIT_CARD)
                ->after('id');
        });
    }
}

プロパティのキャスト

Eloquentではモデルクラスのプロパティに定義することで、インスタンス生成時に別の型に自動キャストしてくれる機能があります。protected $dates = [];に入れておけば自動でCarbonにキャストしてくれるとか、そういうやつです。
laravel-enumでも 同様の機能があり、以下のコードで自動キャストが可能です。

 PaymentType::class,
    ];
}

こうしておくことで何が嬉しいのかと言うと、以下のようにbladeでの記述が減ります。

// 自動キャストしない場合
{{PaymentType::getDescription($order->payment_type)}}

// 自動キャストする場合
{{$order->payment_type->description}}

当初は自動キャストせず前者のように書いてたのですが

  • 「いちいちstaticメソッド呼ぶのかったるいよね?」
  • 「ていうかbladeでこの書き方はイマイチなのでは?」
  • 「何かもっとスマートな書き方ないの?あるよね?」

と思い至り、調べた結果見つけた方法でした。
地味ですが少しでもコード量は減らしたいので!

さいごに

enum、いいですね。昔はこういった実装をする際、DBにマスターテーブル作ってconst.phpとか作って定数を列挙して…みたいなことをしてましたが、大抵const.phpが肥大化して管理が億劫になってました。定義がコード化されて気分がいいです。

おすすめ書籍

nomura

シェア
執筆者:
nomura
タグ: phplaravelenum

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前