はじめに
Laravelのアクセサ・ミューテタを使うと、データベースからデータを取得 / 保存する際に、毎回実行したいデータ加工の処理を定義することができる。
今回はこれらの使用方法を備忘録としてまとめておく。
アクセサ・ミューテタとは?
アクセサ
DBからデータを取得する時に、特定の処理を行う機能。
【使用例】
(1)DBからユーザーの名前を取得する際に、大文字小文字の変換を行う。
(2)DBからユーザーデータを取得する際に、既存カラムを使って作成した新しい属性値も含める。
ミューテタ
データベースへデータを保存する時に、特定の処理を行う機能。
【使用例】
データベースに郵便番号を保存する際に、ハイフンを取り除いて半角に変換した上で保存する。
これらアクセサとミューテタの使用方法を、Readoubleに記載の例を引用して説明する。
Laravel 8.x Eloquent:ミューテタ/キャスト
アクセサの使用方法
モデルにget◯◯Attribute
という名前でメソッドを作成すると、Laravelが自動的にアクセサだと判断してくれる。
この際、メソッド名の◯◯
の部分に加工したいカラム名をアッパーキャメルケースで指定する。
アクセサはDBからのデータ取得時にデータを加工するための機能だが、以下の2通りの使い方ができる。
① DBにあるカラム名と同じカラム名でデータを返す場合
② DBにあるカラムを使って、新しいカラム名でデータを返す(DBのテーブルに実際には存在しないカラムを、独自に作ることができるイメージ)
それぞれの使い方を説明する。
使用方法①:DBにあるカラム名と同じカラム名でデータを返す場合
以下は、DBのusersテーブルに実際に存在する first_name
というカラムの値を加工する例。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* ユーザーの名前の取得
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
これにより、カラムの元の値がアクセサに $value
として渡され、PHPのucfirst関数により最初の文字を大文字に変換した結果の値を返す。
よって例えば、 User::find(1);
のようにデータを取得すると、DBのデータが「hanako」だった場合、レスポンスでは「Hanako」に変換されているということになる。
使用方法②:DBにあるカラムを使って、新しいカラム名でデータを返す場合
アクセサは既存のカラムを使って、新しい属性を作り出してレスポンスに含めることもできる。
以下は、DBのusersテーブルに既存の first_name
と last_name
というカラムを使用して、 full_name
という新しい属性を作成して返す例。
full_name
という属性を作るので、メソッド名は getFullNameAttribute()
とする。
/**
* ユーザーのフルネームの取得
*
* @return string
*/
public function getFullNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
例えば、 User::f``ind(1);
のようにデータを取得すると、DBには full_name
というカラムは存在しなくても、あたかもDBに full_name
というカラムが存在するかのように、返り値には full_name
という属性が含まれている。
以下のように記述することで、DBに存在するカラムと同じように full_name
の値にアクセスすることができる。
$user = App\User::find(1);
$fullName = $user->full_name;
使用方法②の注意点
DBから取得したデータをJSON形式でフロント側にレスポンスとして返す、、というような場面もあるだろう。
モデルのデータを配列やJSONに変換する時に、使用方法②で作成したDBにはカラムが無い属性も含めたい場合は、アクセサの使用に加えてモデルの appends
プロパティに属性を設定する必要がある。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* モデルの配列フォームに追加するアクセサ
*
* @var array
*/
protected $appends = ['full_name'];
}
属性をappends
リストへ追加すると、配列やJSON形式のレスポンスにも含まれるようになる。
またappends
プロパティに設定した属性は、モデルで設定されたvisible
およびhidden
の設定も尊重する。
ミューテタの使用方法
ミューテタを使用すると、DBへのデータ保存時にデータを加工することができる。
モデルにset◯◯Attribute
という名前でメソッドを作成すると、Laravelが自動的にミューテタだと判断してくれる。
この際、メソッド名の◯◯
の部分に加工したいカラム名をアッパーキャメルケースで指定する。
以下は、usersテーブルの first_name
というカラムへデータを保存する際に、PHPのstrtolower
メソッドを使用して、受け取った文字列を全て小文字に変換する例。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* ユーザーの名前を設定
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
ミューテタは入力された値を $value
として受け取る。
$this->attributes['first_name']
でEloquentモデルの first_name
へアクセスできるので、ここに整形後の値を設定する。
さいごに
業務でアクセサが使った記述があったのだが、ルールに沿ったメソッド名で定義すればLaravelが自動的にアクセサとして扱ってくれるというものなので、アクセサを知らずにコードを読んでいると中々仕組みに気付けなかった。
だが知っていれば非常に便利なフレームワークの機能なので、今後はこの機能を自分の引き出しの一つとして、有効な場面で使えるように覚えておきたい。
参考記事