Framework

Laravel Mutator Accessor

投稿日:

たぶん Delphi/C# が起源だと思うんだが、データに紐づく規則や処理をモデルに寄せるパターン(Microsoft:The Repository Pattern)と同等の機能がPHP FrameworkであるLaravelのORM(Eloquent)にあり、流石に超便利だったのでメモっておく。
setter側をMutator、getter側をAccessorという。Mutator, Accessorを簡単にまとめると以下のような感じ。

  • Eloquentインスタンスに対して値をセットする際に必ずあるメソッド(Mutator)を経由する機能
  • Eloquentインスタンスから値をゲットする際に必ずあるメソッド(Accessor)を経由する機能

本家のドキュメントは以下のように続く。

Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model.

データに紐づくルールや処理をモデルに寄せることでコントローラの肥大化を防ぐ機能の一つだが、コントローラとモデルの間の取り決めを規約によって定めることで、コントローラからもモデルからも扱いやすくなる。

例えば、usersテーブルにfirst_nameという名前のフィールドがあったとする。
フィールドには小文字で入力し、使うときは必ず先頭1文字を大文字として使う、というルールがある場合Userモデル側を以下のような規約に従って書く。

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
	/*
	 * Get the user's first name.
	 *
	 * @param  string $value
	 * @return string
	 */
	public function getFirstNameAttribute($value)
	{
		return ucfirst($value);
	}

	/*
	 * Set the user's first name.
	 * 
	 * @param  string $value
	 * @return void
	 */
	public function setFirstNameAttribute($value)
	{
		$this->attributes['first_name'] = strtolower($value);
	}

}

コントローラからfirst_nameフィールドの値を取るコードは以下の通りだが、必ずAccessorを経由し値が返る。フィールドの値が何であれ先頭は必ず大文字になる。ブラウザ等に表示する際に加工する必要がない。

<?php
	$user = App\User::find(1);
	$firstname = $user->first_name;

ブラウザ等からデータが入って来たとき、それをusers.first_nameフィールドに格納する処理を書く際、必ずMutatorを経由する。
「小文字にする」という処理を一切意識しないで良い。

<?php
	$user = App\User::find(1);
	$user->first_name = 'Sally';

コントローラより上は涼しい顔をして重い処理の記述を省略できる。データに紐づくルールが重ければ重いほどモデルに寄せる効果が大きくなる。
例えば、データを暗号化して格納するケースにおいては、暗号化/復号処理をModelに隠蔽しControllerより上からは透過的に平文として扱うなど。

Eloquentは流石に雄弁だ。

-Framework

Copyright© ikuty.com , 2018 AllRights Reserved Powered by AFFINGER4.