どうも、たかふみです
個人で開発中のアプリケーションでEnumを使ってみました。
Enumは業務で携わったプロジェクトでも使っていたので、さらに理解を深めるために個人的にも使ってみようと思ったのがきっかけです。
Ben SampsonさんのBenSampo/laravel-enum
で実装を行いました。
開発環境
root@ade420a5446f:/work/backend# php artisan --version
Laravel Framework 9.3.1
root@ade420a5446f:/work/backend# php --version
PHP 8.1.1 (cli) (built: Dec 18 2021 00:38:05) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
Enumとは
列挙型と呼ばれるデータ型の一つ。
複数の定数を一つのクラスとしてまとめることができる。
使用箇所
id | カテゴリー名 |
---|---|
1 | 野菜 |
2 | 肉 |
3 | 魚 |
DBに「材料のカテゴリー」マスターテーブルがあります。
材料の情報を画面で表示する際に "その材料がどのカテゴリーなのか" を判別して該当する画像を表示します
例)
「にんじん」を表示
にんじん (ingredient_category_id = 1)
→材料カテゴリーのid=1である”野菜”の画像を画面上に表示する
対応前の実装
@if ($recipeIngredients->ingredient_category_id === 1)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/vegetable.png') }}" alt="vegetable"/>
@elseif ($recipeIngredients->ingredient_category_id === 2)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/meat.png') }}" alt="meat"/>
@elseif ($recipeIngredients->ingredient_category_id === 3)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/fish.png') }}" alt="fish"/>
@endif
上記実装の問題点は以下2点あります。
・DB内のidを変えたいときにはblade内のidも修正する必要がある
・blade.phpだけを見ても、どのidがどのカテゴリーか分からない。正しい画像が表示されているのか分からない
画面上にマジックナンバーが記載されているのもイマイチですね。これをEnum使って改善していきます。
Enumのインストール&作成
公式のREADMEい従い、インストール。
composer require bensampo/laravel-enum
インストールできたら、材料カテゴリーのEnumを記載するファイルを作成。
php artisan make:enum IngredientCategory
内容をDBの内容に合わせて変更していきます。
<?php
declare(strict_types=1);
namespace App\Enums;
use BenSampo\Enum\Enum;
final class IngredientCategory extends Enum
{
const VEGETABLE = 1;
const MEAT = 2;
const FISH = 3;
/*
* @param int $id 材料カテゴリーID
* @return stirng 材料カテゴリー名
*/
public static function getIngredientCategoryName(int $id = null)
{
if ($id === self::VEGETABLE) {
return '野菜';
}
if ($id === self::MEAT) {
return '肉';
}
if ($id === self::FISH) {
return '魚';
}
}
}
Enumファイルができたので、早速他のファイルに書いていきましょう。
他ファイルの対応
InitialDatabaseSeeder.php
まずは、DBにマスターデータを入れるSeederをEnumを使って書き換えます。
// 材料カテゴリーのマスターデータ作成
$ingredientCategories = [
[
// id = 1
'ingredient_category_name' => '野菜',
],
[
// id = 2
'ingredient_category_name' => '肉',
],
[
// id = 3
'ingredient_category_name' => '魚',
],
];
DB::table('ingredient_categories')
->insert($ingredientCategories);
↓
// 材料カテゴリーのマスターデータ作成
$ingredientCategories = [];
for ($i=1; $i<=3; ++$i) {
$ingredientCategories[] = [
'ingredient_category_name' => IngredientCategory::getIngredientCategoryName($i),
];
}
DB::table('ingredient_categories')
->insert($ingredientCategories);
blade.php
画面上の画像表示仕分けも書き換えていきます。
@if ($recipeIngredients->ingredient_category_id === 1)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/vegetable.png') }}" alt="vegetable"/>
@elseif ($recipeIngredients->ingredient_category_id === 2)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/meat.png') }}" alt="meat"/>
@elseif ($recipeIngredients->ingredient_category_id === 3)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/fish.png') }}" alt="fish"/>
@endif
↓
@if ($recipeIngredients->ingredient_category_id === App\Enums\IngredientCategory::VEGETABLE)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/vegetable.png') }}" alt="vegetable"/>
@elseif ($recipeIngredients->ingredient_category_id === App\Enums\IngredientCategory::MEAT)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/meat.png') }}" alt="meat"/>
@elseif ($recipeIngredients->ingredient_category_id === App\Enums\IngredientCategory::FISH)
<img class="detailIngredientItemImage" src="{{ asset('images/ingredientCategory/fish.png') }}" alt="fish"/>
@endif
マジックナンバー直書きの箇所をEnumを使って書き換えました。
プロパティ名と画像名を関連づけられるので画像間違いの実装は無くなりそうです。
ただ、blade上にクラス名を記載するのはどうなんですかね...?
調べた限りだと良い方法が無かったので妥協案として実装しましたが、他に綺麗な書き方が合えればコメントいただきたいです。
個人的には、以下の状態にできたのでEnum使って良かったなと思っています。
・Enumについての処理を加えたいならEnumのファイルへ追記する
・blade上にマジックナンバーを直書きしていない
・材料カテゴリーマスターの情報はEnumファイルを見れば良い
それでは!
参考サイト
・BenSampo/laravel-enum
https://github.com/BenSampo/laravel-enum