Sql 是否有一种方法可以从构建器中获取所有查询,特别是获取急切加载的信息
使用Laravel5.8.11我有一个多态性有很多关系一个客户端可以有很多地址,其他东西可以有地址在这种情况下,所以它是多态的。(称为地址) 我还与客户的当前地址保持多态“hasine”关系。(被叫地址) 当我尝试运行此查询时:Sql 是否有一种方法可以从构建器中获取所有查询,特别是获取急切加载的信息,sql,laravel,builder,Sql,Laravel,Builder,使用Laravel5.8.11我有一个多态性有很多关系一个客户端可以有很多地址,其他东西可以有地址在这种情况下,所以它是多态的。(称为地址) 我还与客户的当前地址保持多态“hasine”关系。(被叫地址) 当我尝试运行此查询时: returnclient::with('address')) ->其中('first_name'、'like'、'%'.$search.'%')) ->或where('last_name'、'like'、'%'.$search.'%')) ->get(); 我得到了一
returnclient::with('address'))
->其中('first_name'、'like'、'%'.$search.'%'))
->或where('last_name'、'like'、'%'.$search.'%'))
->get();
我得到了一些奇怪的结果。我得到了所有的客户,但只有最后一个客户有地址
当检查种子数据时,所有其他地址都在那里,如果我通过发送不同的搜索条件来更改结果,最后一个人将始终返回正确的地址,而其他人将始终返回null
这不是UI问题,因为我只是在单元测试中转储结果
以下是客户机对象上关系的代码
/**
*获取与模型关联的地址记录。
*/
公共函数地址():MorphMany
{
返回$this->morphMany(Location::class,'has_Location')->latest();
}
/**
*获取与模型关联的最新地址记录。
*/
公共函数地址():MorphOne
{
return$this->morphOne(Location::class,'has_Location')->latest('id')->limit(1);
}
当我试图找出从数据库中调用的内容时,我试图捕获正在发送的SQL。我只是使用一个简单的函数将完整的sql放在下面,以便于阅读:
函数ddsql($builder,$replace=false)
{
如果(!$replace)
返回ddf([$builder->toSql(),$builder->getBindings()]);
$sql=$builder->toSql();
ddf(Str::replaceArray(“?”,$builder->getBindings(),$sql));
}
ddf()基本上是dd(),但有一些助手显示从backtrace日志调用函数与此无关
我在原始代码块上使用它,如下所示
ddsql(
客户端::带('地址')
->其中('first_name'、'like'、'%'.$search.'%'))
->或where('last_name'、'like'、'%'.$search.'%'))
);
它返回第一个查询,但从不返回问题所在的急加载步骤
Array
[
"select * from `clients` where `first_name` like ? or `last_name` like ?",
[
"%co%",
"%co%"
]
]
但是,我只从构建器返回第一个查询
有没有办法获取所有查询
任何建议都将不胜感激
更新: Per@tim lewis,(谢谢)我更新了我正在使用的函数,它很难看,但是完成了任务
/**@测试*/
公用函数客户端\u匹配\u搜索\u返回\u及其\u地址(){
$client1=ObjectFactory::clientWithAnAddress(['client'=>['first\u name'=>'Test1']]);
$client2=ObjectFactory::clientWithAnAddress(['client'=>['first\u name'=>'Test 2']]);
$client3=ObjectFactory::clientWithAnAddress(['client'=>['first\u name'=>'Test 3']]);
ddSqlCollection(函数(){return Client::with('address')->get();});
}
//其中ddSqlCollection如下所示
函数ddSqlCollection($callback,$replace=false){
$callback=$callback?:函数(){
返回true;
};
DB::flushQueryLog();
DB::enableQueryLog();
$callback();
DB::disableQueryLog();
ddf(DB::getQueryLog());
}
我确信有一种更好的方法,我仍然不确定为什么我得到的数据与我认为SQL应该返回的数据不匹配,但是我将在一个更集中的后续问题中询问这些数据
以下是预期的输出:
"ddSqlCollection(["Closure"])"
"Tests\Feature\Clinet\SearchTest\clients_matching_search_are_returned_with_their_addresses([])"
"-------------------------------------------"
array:2 [
0 => array:3 [
"query" => "select * from "clients""
"bindings" => []
"time" => 0.06
]
1 => array:3 [
"query" => "select * from "locations" where "locations"."has_location_id" in (1, 2, 3) and "locations"."has_location_type" = ? order by "id" desc limit 1"
"bindings" => array:1 [
0 => "App\Client"
]
"time" => 0.19
]
]
不幸的是,
->toSql()
没有显示完整的查询,但是有一种方法可以打开查询日志并显示上一次查询运行,包括子查询和绑定,这就是使用enableQueryLog()
函数:
\DB::connection()->enableQueryLog();
然后,在执行查询后,您可以立即dd()
显示查询结果。例如:
$user = User::with(["role"])->first();
$lastQuery = collect(\DB::getQueryLog())->last(); // or end(\DB::getQueryLog());
dd($lastQuery);
在我的情况下,这将导致以下结果:
array:3 [▼
"query" => "select `roles`.*, `role_users`.`user_id` as `pivot_user_id`, `role_users`.`role_id` as `pivot_role_id` from `roles` inner join `role_users` on `roles`.`id` = `role_users`.`role_id` where `role_users`.`user_id` in (?)"
"bindings" => array:1 [▼
0 => 1
]
"time" => 0.9
]
注意:使用collect(\DB::getQueryLog())->last()
只是一种只返回最后一次查询运行的快速方法。如果要查看当前请求中运行的所有查询,只需执行以下操作:
dd(\DB::getQueryLog());
感谢@tim lewis的查询日志想法,我不确定我是否可以在评论中显示它,但我确实使用此函数获得了完整的查询日志,事实上,它向我显示了我希望看到的数据,我相信我希望看到的数据,但它似乎没有以我期望的方式绑定。这确实回答了部分问题。我不确定协议是否要求我关闭部分未回答的问题,或者等到有完整的答案。事实上,根据问题的标题,我认为这回答了“有标题”的问题,所以希望我会关闭它,希望不会因为问这个问题的更具体版本而受到惩罚。没问题。这取决于你:)如果你觉得你可以在这个问题上展开讨论,那就继续吧,但有时候最好用新问题来提出新问题。无论哪种方式,如果问题有帮助,就放弃对它的投票(如果你可以/想要),然后决定是否要标记为“接受”,或者扩展。不管怎样欢呼;很高兴我能帮上忙。我帮了忙,但因为我不熟悉堆栈溢出,所以它没有出现。我想最终会的。