使用Laravel whenLoaded()深于一个级别

时间:2018-04-22 10:49:19

标签: php laravel

如何将whenLoaded()用于更深层次的关系?好像人们只能使用whenLoaded这样的第一个关系深度:

'season' => $this->whenLoaded('origin', function () {
    return new SeasonResource($this->origin->season);
}),

但是Laravel,如果origin被加载,而不是season,Laravel将加载它,这会产生N + 1问题。 originseason关系都是有条件的,并不总是使用。因此我想使用这样的东西:

$this->whenLoaded('origin.season', ...)

或者这个:

'season' => $this->whenLoaded('origin', function () {
     return new SeasonResource($this->origin->whenLoaded('season'));
}),

这些都不奏效。我认为更深层次的关系不会存储在模型本身上,而在第二种情况下,查询构建器中不存在whenLoaded()

  

如何将whenLoaded()用于更深层次的关系?

3 个答案:

答案 0 :(得分:4)

我认为没有实现的原因是因为它只对hasOnebelongsTo关系(返回对象的关系,而不是集合)有意义。

但如果是这种情况,你可以这样做:

'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