今までlaravelのモデルをDBバインドにしか使ってませんでした。
アクセサ、ミューテタで結構賢くすることができたのでメモします。
アクセサ
モデルの値を取得する時にひと手間加えてくれる。
例)created_atを表示
$model->created_at; // 2024-04-17T10:02:20.000000Z
$model->created_at->format('Y/m/d H:i:s'); // 2024/04/17 19:02:20
モデルにアクセサを設定すると↓
Models\user.php
use Illuminate\Database\Eloquent\Casts\Attribute; // 忘れずに
//アクセサ
public function createdAt() {
return Attribute::make(
get: function () {
return $this->created_at->format('Y/m/d H:i:s');
}
);
}
こうなります↓
呼び出し側
$model->created_at; // 2024/04/17 19:02:20
モデルではキャメルcreatedAt()
なのに、
呼び出す時はスネークcreated_at
でもオッケーです🙆♀️
■ 関数名は変えてもオッケーです。
Models\user.php
//アクセサ
public function createdDateTime() {
return Attribute::make(
get: function () {
return $this->created_at->format('Y/m/d H:i:s');
}
);
}
呼び出し側
$model->created_datetime; // 2024/04/17 19:02:20
■ 他のカラムを参照する場合。
例)is_member, is_admin, is_gestフラグを配列にする。
Models\user.php
protected function authorities()
{
return Attribute::make(
//アクセサ
get: fn ($value, $attributes) => array_filter([
$attributes['is_member'] ? 'member' : '',
$attributes['is_admin'] ? 'admin' : '',
$attributes['is_gest'] ? 'gest' : '',
]),
);
}
呼び出し側
$model->authorities; // ['member', 'admin', 'gest']
ミューテタ
モデルの値を格納する時にひと手間加えてくれる。
アクセサと逆の操作。
Models\user.php
protected function authorities()
{
return Attribute::make(
// ミューテタ
set: fn ($value) => [
'is_member' => in_array('member', $value),
'is_admin' => in_array('admin', $value),
'is_gest' => in_array('gest', $value),
],
);
}
モデルに値を入れるとミューテタを通る。
呼び出し側
$model->authorities = ['member', 'admin'];
// $model->is_member 1
// $model->is_admin 1
// $model->is_gest 0
■ アクセサ、ミューテタを両方設定する時はこう
Models\user.php
protected function authorities():
{
return Attribute::make(
//アクセサ
get: fn ($value, $attributes) => array_filter([
$attributes['is_member'] ? 'member' : '',
$attributes['is_admin'] ? 'admin' : '',
$attributes['is_gest'] ? 'gest' : '',
]),
// ミューテタ
set: fn ($value) => [
'is_member' => in_array('member', $value),
'is_admin' => in_array('admin', $value),
'is_gest' => in_array('gest', $value),
],
);
}
Models\user.php
protected function isMember()
{
return Attribute::make(
get: fn ($value) => $value ? 'member' : '',
set: fn ($value) => $value ? 1 : 0,
);
}
キャスト cast
アクセサ、ミューテタを設定するほどではないが型は守って欲しい時。
Models\user.php
protected $casts = [
'is_member' => 'boolean',
'is_admin' => 'boolean',
'is_gest' => 'boolean',
];
呼び出し側
$model->is_member = '猫'; // 1
$model->is_admin = 1111; // 1
$model->is_gest = null; // 0
入れても出してもその型にキャストしてくれる。
トレイト trait
アクセサ、ミューテタ、その他の機能を切り出して共通化する。
こうやって新しいクラスを作っておくと。
App\Traits\DateTrait.php
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Casts\Attribute;
trait DateTrait {
public function createdAtAsDate(){
return Attribute::make(
get: function () {
return $this->created_at->format('Y/m/d');
}
);
}
}
これだけで使える。
(SoftDeletes、HasFactoryなどと同じ)
Models\user.php
// use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Illuminate\Database\Eloquent\SoftDeletes;
use App\Traits\DateTrait;
class User extends Model
{
// use HasFactory;
// use SoftDeletes;
use DateTrait;
...
呼び出し側
$model->createdAtAsDate; // 2024/04/17
いかがだったでしょうか。
・アクセサ
・ミューテタ
・キャスト
・トレイト
を使ってモデルを賢くさせましょう!