Php 急加载约束和whereHas
考虑这个查询:Php 急加载约束和whereHas,php,sql,laravel,eloquent,Php,Sql,Laravel,Eloquent,考虑这个查询: $query = Ticket::whereHas('user', function($q) use ($search) { $q->where(function($q) use ($search) { $q->where('name', 'LIKE', '%'. $search .'%')->orWhere('username', 'LIKE', '%'. $search .'%'); }); })->pagina
$query = Ticket::whereHas('user', function($q) use ($search)
{
$q->where(function($q) use ($search)
{
$q->where('name', 'LIKE', '%'. $search .'%')->orWhere('username', 'LIKE', '%'. $search .'%');
});
})->paginate(10);
还有这个:
$query = Ticket::with(array('user' => function($q) use ($search)
{
$q->where('name', 'LIKE', '%'. $search .'%')->orWhere('username', 'LIKE', '%'. $search .'%');
}))->paginate(10);
在测试过程中,第一个查询在搜索John的过程中返回了50张罚单中的47张,正如预期的那样
通过第二个查询复制搜索,将返回50个结果,全部结果
更准确地说,在第二个查询中,当不应该返回的3行中有一行在分页中时,当尝试访问诸如$ticket->user->name之类的属性时,它会中断。否则,一切都不会中断
为什么第二个查询会失败?在第二个查询中,如下所示:
$query = Ticket::with(array('user' => function($q) use ($search) {
$q->where('name', 'LIKE', '%'. $search .'%')->orWhere('username', 'LIKE', '%'. $search .'%');
}))->paginate(10);
您正在获取所有票证,因为您没有筛选票证,例如,请思考以下查询:
$query = Ticket::with('user')->paginate(10);
select * from `tickets` where `tickets`.`deleted_at` is null
select * from `users` where `users`.`ticket_id` in (?, ?, ?, ?, ?, ?, ?, ?) and `name` ... ?
select * from `tickets` where `tickets`.`deleted_at` is null and (select count(*) from `users` where `users`.`ticket_id` = `tickets`.`id` and `name` LIKE ? ...) >= ?
您将得到什么,所有用户的票证,但通过添加约束,您只过滤用户而不是票证,因此在这种情况下,您的查询将如下所示:
$query = Ticket::with('user')->paginate(10);
select * from `tickets` where `tickets`.`deleted_at` is null
select * from `users` where `users`.`ticket_id` in (?, ?, ?, ?, ?, ?, ?, ?) and `name` ... ?
select * from `tickets` where `tickets`.`deleted_at` is null and (select count(*) from `users` where `users`.`ticket_id` = `tickets`.`id` and `name` LIKE ? ...) >= ?
因此,首先在没有任何过滤的情况下选择票据,然后对于用户,将执行另一个查询,但在第一个查询中,将执行另一个查询。因此,在第二个示例中,由于您的所有票证都没有用户,因此在不包含相关用户的票证模型上执行$ticket->user->name时,会出现错误,因为没有user So no name属性
whereHas的第一个查询可能如下所示:
$query = Ticket::with('user')->paginate(10);
select * from `tickets` where `tickets`.`deleted_at` is null
select * from `users` where `users`.`ticket_id` in (?, ?, ?, ?, ?, ?, ?, ?) and `name` ... ?
select * from `tickets` where `tickets`.`deleted_at` is null and (select count(*) from `users` where `users`.`ticket_id` = `tickets`.`id` and `name` LIKE ? ...) >= ?
如果要查看生成的每个查询,请在所有查询之后使用以下命令:
dd(DB::getQueryLog());
这将返回由查询生成器生成并执行的查询数组。您想做什么?我想根据上面的like子句检索属于用户的票证。您有一个有效的票证,第一个。我对另一个很好奇。查看DB::getQueryLog正是您所说的。我真的很感谢你对狼人先生的解释。