前置き
とあるプロジェクトにて、DBから取得してきたあるカラム値を、全て変換してからAPIでレスポンスするという要件があった。
単純に考えると「foreachで全件回しながら処理する」になるんだけど、なんかいい感じに出来ないかなーと思った時にLaravelにはアクセサという機能がある事を知ったので、使ってみようと思います。
環境
$ php -v
PHP 7.4.29 (cli) (built: May 11 2022 14:21:44) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
$ php artisan -V
Laravel Framework 8.78.1
やりたいこと
一言で言うと、"DBにdate型で格納されている値を、全てunixタイムスタンプ形式に変換して返す。"という要件。
元々unixタイムスタンプ形式で入っていれば取得するだけで良かったんだけど、今回は難しいのでバックエンド側で対応する事となりました。
アクセサを使って実現する方法
公式に分かりやすく載ってますが、一応。
Laravel 8.x Eloquent:ミューテタ/キャスト
functionを定義する
まず前提として、Modelが定義されている事が前提となります。
定義方法としては、下記の通り。
アクセサは、アクセス時にEloquent属性値を変換します。
アクセサを定義するには、モデルにget{Attribute}Attributeメソッドを作成します。
{Attribute}は、アクセスするカラムのアッパーキャメルケース(studly case)の名前です。
カスタマイズしたいカラム名のアッパーキャメルケースを繋げて、get○○Attribute
メソッドを定義するって感じ。
本例では、カラム名がLAST_UPDATE
だったので、下記のように記述して実現できました。
/**
* 更新日時をUnixタイムスタンプ形式で返す
*
* @param string
*
* @return int
*/
public function getLastUpdateAttribute($value)
{
$last_update = new Carbon($value);
return $last_update->getTimestamp();
}
簡単ッ!!
カスタマイズされたカラム値にアクセスする
上記のアクセサの設定を行えば、あとはカラム値取得時に自動で処理が行われ結果が返ります。
確認してみます。
$ php artisan tinker
Psy Shell v0.10.12 (PHP 7.4.29 — cli) by Justin Hileman
>>> $user = User::find(1);
=> App\Models\User {#3666
id: 1,
.
.
.
last_update: "2022-03-23 18:26:14",
}
$ user->last_update
=> 1648027574
※一部結果を割愛してます。
想定通り、unixタイムスタンプでlast_updateが取得できました!
パフォーマンスに関しては検証出来てませんが、foreachで回すよりスッキリ書けますし、記述を忘れる心配もないので使える場面があれば積極的に使って良いのかな?と思いました。
終わりに
Laravelのアクセサを使用してみました。
今回は取得値をカスタマイズするという用件でしたが、逆にDBに設定する値をカスタマイズする場合はミューテタを使用すればできるみたいです!
アクセサと設定方法も似ているので、簡単に使えそう。
また、単純に属性キャストするだけであれば、$casts
配列に追加するだけで出来るみたい。
/**
* キャストする必要のある属性
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
こちらも覚えておいて損はなさそうなので、頭の片隅の置いておこう。。