withCasts()、ぜひ知ってほしい
ご無沙汰してます、さわちゃんです。
今日はLaravelの小ネタとして、withCasts()という便利メソッドについて紹介をしたいと思います。
前提条件
- PHP 8.2.6
- Laravel Framework 10.5.1
- PostgreSQL 15.2
(MySQLでも問題ないです)
ケーススタディ
みなさん、素のSQLを使って値を取得するとき、型によっては自分でキャストをしないといけなくて面倒だな〜って思うこと、ありませんか?
例えば、注文(orders)と支払い(payments)のテーブルがあって、注文に紐づく最新の支払日が欲しい!ってなったとします。
(Laravel側でもできますが、メモリ節約のためにSQLでなんとかしたい気持ちであると仮定します)
コードは以下のようになります。
$order = Order::query()
->select(DB::raw(‘MAX(payments.created_at) as latest_payment_date’))
->join(‘payments’, ‘orders.id’, ‘=‘, ‘payments.order_id’)
->first();
dd($order->latest_payment_date);
=> “2023-07-10 11:02:20”
はい。
値はstringになるので、Carbon(またはCarbonImmutable)として値が欲しい場合は、
Carbon(またはCarbonImmutable)::create($order->latest_payment_date)
としてあげる必要がありますね。
これが面倒くさい!どうにかしたい!Eloquentモデルの$castsみたいに自動でやってほしい!って思うこと、あると思います。
そこで活躍するのが今日の本題、\Illuminate\Database\Eloquent\Builder::withCasts()です。
withCasts()の使い方
Eloquentモデルのプロパティ(テーブルのカラム)以外の値を取得するとき、型を指定したらキャストしてくれるメソッドです。
Laravel 7系から追加されました。(参考)
使い方はEloquentモデルの$castsとほとんど同じです。
$order = Order::query()
->select(DB::raw(‘MAX(payments.created_at) as latest_payment_date’))
->join(‘payments’, ‘orders.id’, ‘=‘, ‘payments.order_id’)
->withCasts([
‘latest_payment_date’ => ‘datetime’
])
->first();
dd($order->latest_payment_date);
=>
Carbon\CarbonImmutable {
date: 2023-07-10 11:02:20.0 Asia/Tokyo (+09:00)
// 他省略
}
このように、CarbonImmutableとして値を取得することができました。
便利ですね。
素のSQLを使って値を取得するとき、プリミティブな型(integerやboolean)については勝手にキャストしてくれますが、日付などはこのようにキャストしてあげると取得してからわざわざ自力でキャストする必要がなくなります。
ぜひ使ってみてください。
お疲れ様でした。