はじめに
laravel使ってて、Eloquentのクエリからのコレクションの使い勝手がヤバかったので(こういうのに慣れてる人にとっては当たり前かもしれませんが)、とりあえずメモを残します。
例
例えば車モデルを使って車一覧に利用可能なフラグを追加したい時、条件がカオスすぎてクエリ作るのを諦めてしまったとします。
1クエリだけで頑張ろうとすると大変ですが、クエリ&コレクションだとこんなにすっきり書ける!?
コントローラ
class HogeController extends Controller
{
/**
* 公開中の車をJSONで取得
*/
public function getCarList(Request $request){
$from_at = $request->get('from_at');
$to_at = $request->get('to_at');
// 利用可能な車のコレクションを取得
$available_cars = Car::getAvailableCars($from_at, $to_at);
// 車リストに利用可能フラグを追加して車種別にグルーピングしてjsonで返す
$cars = Car::query()
->where('is_publish', '=', 1)
->get()
->map(
function ($row) use($available_cars){
$row['is_available'] = $available_cars->find($row['id']) ? 1 : 0;
return $row;
}
)->groupBy('type_id');
return response()->json($cars);
}
}
モデル
class Car extends Model
{
/**
* 利用可能な車を取得
*/
public static function getAvailableCars($from_at, $to_at)
{
return Car::query()->whereNotIn('id',
function ($query) use ($from_at, $to_at) {
$query->select('car_id')
->from('reservations')
->whereRaw("見るのも嫌な条件..",[$from_at, $to_at])
->whereNull('cancel_at');
})->where('is_publish', '=', 1)->get();
}
}
この程度ならクエリだけでいけるだって!?
でもこういう方法が役に立つ場面に今後絶対出くわすはず!
おわりに
やっぱりDoctrineよりEloquentが好き