【Laravel】入力制御におすすめ Eloquentのミューテータ

こんにちは。今回はEloquentのミューテータ機能を説明していきます。

ミューテータとは何か

ミューテータとはEloquentモデルに値を設定する際に実行する処理です。モデルに値が設定される前に実行されるので、値の検査や変換を行いたい場合に便利な機能です。

ミューテータの作成手順

例を用いてミューテータの作成手順を説明します。

商品の予約を管理するOrder(注文)モデルにはorder_no(注文番号)属性が存在します。order_noは数字のみを受付け、数字が6桁に満たない場合は、足りない桁の部分をゼロで埋めて登録しなければなりません。

まずはミューテータを使用しないで上記の要件を満たすコードを書いてみましょう。Orderモデルを生成し、1項目ずつプロパティに代入していきます。order_noにはstr_pad関数でゼロ埋めしたあと、値をセットします。

		$orderNo = '1';

		// 注文データを1件作成
		$order = new Order;
		$order->order_no = str_pad($orderNo, 6, '0', STR_PAD_LEFT);
		$order->date = '2021-08-30';
		$order->user_id = '1';
		$order->kingaku = '3000';
		$order->shohin = 'Book C';
		$order->save();

このコードは誤りではありませんし、何の問題もなく動作します。しかし、コードのメンテナンス性を考慮すると1つ問題があります。注文を生成、更新する処理では毎回ゼロ埋め処理を記述しなければなりません。コードが重複するため、あまり変更に強くありません。

そこで登場するのがミューテータです。ミューテータはorder_noに代入する場合に必ず実行されるメソッドです。ミューテータの中でゼロ埋め変換処理を行えば、1箇所に記述するだけで全てのOrder作成、更新処理をカバーすることができます。これを使わない手は無いでしょう。

ミューテータは対象のEloquentオブジェクト内にset[属性名]Attributeという名前でメソッド定義することで作成できます。今回の場合はOrderモデル内にsetOrderNoAttributeという名前で定義しました。この中に先程のゼロ埋め処理を書きます。

class Order extends Model
{
    use HasFactory;

	public function setOrderNoAttribute($value)
    {
        $this->attributes['order_no'] = str_pad($value, 6, '0', STR_PAD_LEFT);
    }
}

次に呼び出し側のコードを変更します。ゼロ埋め処理が不要になりましたので撤廃します。

    public function index () {
		$orderNo = '1';

		// 注文データを1件作成
		$order = new Order;
		$order->order_no = $orderNo;
		$order->date = '2021-08-30';
		$order->user_id = '1';
		$order->kingaku = '3000';
		$order->shohin = 'Book C';
		$order->save();
    }

他の項目と同様、ただ代入しているだけですが、ミューテータは背後で動作しています。実際order_noに登録した値を見ると000001という値で登録されています。

まとめ

今回はミューテータについて解説しました。ミューテータを使うべきかどうかは、Eloquentモデルの生成、更新を行う機能で同じような処理を書いているかどうかで判断できます。簡単にリファクタリングできるので、開発中のコードなどを一度見直してみると良いかと思います。

Laravel

Posted by kobainmac