能否在另一个Eloquent查询中使用Eloquent/Builder实例?
能否在Eloquent查询中复用Builder实例?
当然可以在一个Eloquent查询里复用另一个Builder实例,但你尝试的User::where('posts', $postsQuery)写法是行不通的——Eloquent会把这个Builder实例当成普通的字段值来处理,根本没法识别你要关联posts的查询条件。下面给你两种正确的实现方式:
方法一:用whereHas结合mergeConstraintsFrom
如果你本来就是用whereHas来关联posts关系,那可以预先定义好posts的查询,再通过mergeConstraintsFrom把约束合并进去:
// 先定义好posts的查询条件 $postsQuery = Post::where('great_post', true); // 在User的whereHas里复用这个查询 $users = User::whereHas('posts', function($query) use ($postsQuery) { // 合并预先定义的查询约束 $query->mergeConstraintsFrom($postsQuery); })->get();
mergeConstraintsFrom方法会把$postsQuery里的所有where条件、orderBy、limit等约束都合并到当前的关联查询中,完美实现复用。
方法二:用whereExists直接复用查询
如果你只是需要检查用户是否存在符合条件的posts,也可以用whereExists来实现,这种方式更直接:
// 定义关联到users表的posts查询 $postsQuery = Post::select(DB::raw(1)) ->whereColumn('posts.user_id', 'users.id') ->where('great_post', true); // 用whereExists筛选用户 $users = User::whereExists($postsQuery)->get();
这里要注意,whereExists里的查询必须通过whereColumn把posts表的user_id和users表的id关联起来,不然查询会没有关联条件,结果不对。
这两种方法都能实现你想要的“拆分查询、复用Builder实例”的需求,根据你的实际场景选就行~
内容的提问来源于stack exchange,提问作者ndberg
相关产品推荐
相关产品推荐

