初学者ですので、間違っていたら厳しめに教えてください
はじめに
Laravelの機能「アクセサ」「ミューテタ」「キャスト」についてです。
これらの機能の共通点は、Eloquentモデルインスタンスのプロパティ設定に関わるというところです。
アクセサ / Accessors
アクセサは定義したプロパティにアクセスする際に、定義した形で返してくれる機能です。
Eloquentモデルに新たなプロパティを作成するイメージです。
実際に作成するわけではありませんが、作成したかのように振舞ってくれます。
定義方法
モデルクラスの中で宣言します。
まず、モデルクラスの中に get〇〇Attribute メソッドを追加し、returnでどういった値を返すか記述します。
「〇〇」の部分は、定義したいプロパティ名を キャメルケース で書きます。
※Laravel9.x から定義方法が若干変わってるっぽい。これはLaravel 8.xです。
class User extends Model
{
public function getNameWithAgeAttribute() // name_with_ageプロパティを定義したい。
{
return $this->name."(".$this->age.")";
}
}
例えば上記のように宣言すると、
$user = User::Find(1);
$user->name_with_age // YamadaTarou(20) みたいな感じで出力される
このようにして、スネークケースで本来のプロパティのように呼び出すと使えます。
既存のプロパティを変換
既にあるNameプロパティを別の形で出力したい場合、
class User extends Model
{
public function getNameAttribute($value) // 引数に$value
{
return ucFirst($value);
}
}
と記述すると、そのプロパティを呼び出す際に変換されて出力されるようになります。
DBには、変換された値は保存されません。これはミューテタと違う部分です。
ミューテタ / Mutators
ミューテタは定義したプロパティを 設定する(記録する) 際に、定義した形に変換してくれる機能です。
アクセサはアクセスする際でしたが、ミューテタの場合は記録する際に変換してくれます。
定義方法
アクセサと大差ありませんが、set〇〇Attributeメソッドをモデルクラスに記述することで定義できます。
※Laravel9.x から定義方法が若干変わってるっぽい。これはLaravel 8.xです。
class User extends Model
{
public function setNameAttribute($value)
{
$this->attributes['name'] = strtoupper($value);
}
}
これは変換した値を、Eloquentモデルインスタンス内のattributes配列を、上書きしているイメージです。
これを定義した状態で、Nameプロパティをセットすると、大文字に変換されてDBに記録されます。
こういったことも可能です。
class User extends Model
{
public function setAllValuesAttribute(Array $value)
{
$this->attributes['name'] = $value[0];
$this->attributes['age'] = $value[1];
}
}
これは配列を$user->all_valuesにセットすれば、一度に値を記録することが可能になります。
キャスト / Attribute Casting
キャストは型変換程度であれば、アクセサやミューテタを使ってメソッドを定義しなくても、変換できる機能です。
定義方法
モデルクラスでcastsプロパティを定義することでできます。
プロパティ名と、キャストする型を宣言します。
class User extends Model
{
protected $casts = [
'is_active' => 'boolean',
];
}
どの型が指定できるかは、ドキュメントを参照してください。