【发布时间】:2017-11-29 11:18:05
【问题描述】:
我有 3 个这样定义的模型:
class Driver extends Model
{
public function provider(){
return $this->belongsTo(Provider::class);
}
}
class DriverPhone extends Model
{
public function provider(){
return $this->belongsTo(Provider::class);
}
}
class Provider extends Model
{
public function drivers(){
return $this->hasMany(Driver::class);
}
public function driverPhones(){
return $this->hasMany(DriverPhone::class);
}
}
现在 - 我想获取所有可用的 Drivers,其 Provider DriverPhones 符合给定标准。我认为这样做是可行的方法:
Driver::with(['provider.driverPhones' => function($query) use ($phone_uuid){
$query->where('uuid', $phone_uuid);
}]);
当我通过以下方式分析查询时:
var_dump($phone_uuid, Driver::with(['provider.driverPhones' => function($query) use ($phone_uuid){
$query->where('uuid', $phone_uuid);
}])->toSql()); exit;
它给了我:
select * from `drivers` where `drivers`.`deleted_at` is null
然而,当我使用whereHas 时,结果集是正确的:
Driver::whereHas('provider.driverPhones', function($query) use ($phone_uuid){
$query->where('uuid', $phone_uuid);
})->get()`
我错过了什么吗?
后续问题 - 对于给定的其他模型:
class Journey extends Model
{
public function coach(){
return $this->belongsTo(CoachId::class);
}
}
class Coach extends Model
{
public function journey(){
return $this->belongsTo(Journey::class);
}
}
如果我搜索Journey::with('coach', 'journeyLocations')->whereHas('coach', [my subquery]),它会找到正确的Journey,但尝试访问coach 却给我null。如果我省略with,则访问正确的coach 属性,但当然会运行多个查询。
那么 - with 是怎么回事?
【问题讨论】:
-
尝试使用
with()和whereHas()的组合,它们使用相同的子查询$query->where('uuid', $phone_uuid);,看看是否返回所需的查询结果。 -
@TimLewis - 对不起,我不明白;我以为我使用的是相同的子查询
-
您的查询应该是
Driver::with(...)->whereHas(...)->get();,->with()和->whereHas()使用相同的子查询。我在您的问题中没有看到这一点;只有一个使用->with()的实例和一个使用->whereHas()的实例。也许将您的最终查询编辑到问题中,我可能读错了。 -
@TimLewis - 我的印象是
with包含所有关系(使用连接),因此只运行一个查询(然后根据一个查询的结果构建关系模型),而whereHas执行子查询,有效地运行了两个。 -
一开始我也是这么想的,但是每当我想用
whereHas()约束我的原始查询并包含->with()的关系时,我不得不同时使用两者来完成这个.试一试,使用dd()检查结果
标签: php laravel eloquent laravel-5.3 eager-loading