如何将whenLoaded()用于更深层次的关系?好像人们只能使用whenLoaded
这样的第一个关系深度:
'season' => $this->whenLoaded('origin', function () {
return new SeasonResource($this->origin->season);
}),
但是Laravel,如果origin
被加载,而不是season
,Laravel将加载它,这会产生N + 1问题。 origin
和season
关系都是有条件的,并不总是使用。因此我想使用这样的东西:
$this->whenLoaded('origin.season', ...)
或者这个:
'season' => $this->whenLoaded('origin', function () {
return new SeasonResource($this->origin->whenLoaded('season'));
}),
这些都不奏效。我认为更深层次的关系不会存储在模型本身上,而在第二种情况下,查询构建器中不存在whenLoaded()
。
如何将whenLoaded()用于更深层次的关系?
答案 0 :(得分:4)
我认为没有实现的原因是因为它只对hasOne
和belongsTo
关系(返回对象的关系,而不是集合)有意义。
但如果是这种情况,你可以这样做:
'season' => $this->when(
$this->relationLoaded('origin') &&
$this->origin->relationLoaded('season'),
function () {
return new SeasonResource($this->origin->season);
}
),
基本上,使用->when
代替->whenLoaded
并手动检查是否使用模型上的->relationLoaded
公共方法加载了关系。
答案 1 :(得分:0)
对于遇到此问题并寻找多对多关系的任何人,我找到了解决方案。
假设你有类似的东西
User ---> user_lived_cities ----> city
表结构为
user_lived_cities
user_id
| city_id
------ | ------
cities
id
| name
------ | ------
您想加载用户居住的城市,例如
User::with('livedCities.city')->take(n)->get();
在资源中,你可以像这样操作值
$livedCityRelation = $this->whenLoaded('livedCities');
$livedCities = $this->when(!empty((array)$livedCityRelation), function () use ($livedCityRelation) {
if ($livedCityRelation instanceof MissingValue) return []; // the relation has no value
$relationLoaded = count($livedCityRelation) /* Remember: It's a collection */ && $livedCityRelation[0]->relationLoaded('city');
return $relationLoaded ? $livedCityRelation->pluck('city') : []; // you can manipulate as per you need. I'm just extracting the city relation from here
});
在 toArray
方法中的资源中,您可以返回
return [
...,
'lived_cities' => City::collection($livedCities),
];
请记住,此时 $livedCities
基本上是一个集合,您可以随意操作它。
如果我只想返回一组城市名称,我也可以这样做
$livedCities->pluck('name')
您可以根据自己的意愿应用任何想要操作的 collection method。
不要忘记在顶部导入
use Illuminate\Http\Resources\MissingValue;
答案 2 :(得分:0)
您可以依次检查每个嵌套关系。例如:
cardio = donnees %>%
select(`Nausées/vomissements`,Vertige,Nystagmus,`Ataxie:Démarche ébrieuse`,`Motif si pas HINTS`,
Alcool,Tabac,`atcd neuro`,Dyslipidémies,Diabète) %>%
filter(Alcool == "Yes" |
Tabac == "Yes"|
`atcd neuro` == "3" |
Dyslipidémies == "Yes"|
Diabète == "Yes")
others <- dplyr::anti_join(donnees, cardio)
这不是我的解决方案,但它解决了我的问题 - 发布因此它可能会帮助其他人,因为这很难找到。所有功劳都归功于 SaeedPrez:
https://laracasts.com/discuss/channels/eloquent/this-relationloaded-for-distant-relationships