eloquentの検索で、既存のリレーションで動的にwhere条件を追加して、withで取得したい!
やっている事は同じだけど、withの方が早いし、シンプル
親子リレーションで、親子どっちの条件でも検索できて、子の検索(or親の検索)に引っかかった親子の組み合わせcollectionだけ取得したい!
参考URL
Laravel eloquant の with にて結合先テーブルのカラムを where 条件にしたい
レビュー星5の投稿をユーザ別に取得したい!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$query = User::query(); // WhereHasで、レビュー星5を持つユーザを抽出 if(!empty($request['stars'])){ $query->WhereHas('posts', function ($query) use ($request){ $query->where('stars', $request['stars']); }); } // 既存のリレーションにwhere条件を追加できる $with = function ($q) use ($request) { $q->where('stars', $request['stars']); }; // 指定されたwhere条件で、withを使ってリレーション先のレコードを取得できる! $users = $query->with(['posts' => $with, '他のリレーションとか']) ->paginate($paginate)->appends( // paginate()のためにgetパラメータに検索条件を付与 $request->query() // getパラメータ全渡し ); |
同じ条件を二箇所に書くのは良くないな。関数化しよう
1 2 3 4 5 6 7 8 9 |
// フロアのwhere条件を一箇所で記述(WITHとWhereHas) public static function post_where($query, $request) { // この中にpost(リレーション先のwhere条件)を書く if(!empty($request['stars'])){ $query->where('stars', $request['stars']); } return $query; } |
whereHasも、リレーション先とリレーション元のレコード数が多くなければ、2~3秒で取得できるから、まあいいか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$query = User::query(); // リレーション先の条件で検索 $query->WhereHas('posts', function ($query) use ($request){ self::post_where($query, $request); }); // 既存のリレーションにwhere条件を追加できる $post_with = function ($q) use ($request) { self::post_where($q, $request); }; $users = $query->with(['posts' => $post_with, 'address']) ->paginate($paginate)->appends( // paginate()のためにgetパラメータに検索条件を付与 $request->query() // getパラメータ全渡し ); |
whereHasよりwhereInの方が早いらしいけど、あんまり変わらない気が…。
1 2 3 4 5 6 7 8 |
// リレーション先の条件で検索 if(!empty($request['starts'])){ $query->whereIn('user_id', Post::query() ->select('posts.user_id') ->where('stars', $request['f_tsubo']) ); } |