Вложенные элементы с Pivot -> дети не получают данные Pivot - PullRequest
0 голосов
/ 06 октября 2019

Я пытаюсь создать возможность вложенности items для моей user модели.

На самом деле, каждый user может иметь множество items, которые могут иметь children своих собственныхтип (item).

Это отношение пользователя к item:

   /**
     * @return \Illuminate\Database\Eloquent\Relations\belongsToMany
     */
    public function items()
    {
        return $this->belongsToMany(Item::class)->withPivot( 'value'');
    }

Вот как разрешается children:

   /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function children()
    {
        return $this->hasMany(Item::class, 'parent_id');
    }

Теперь - благодаря вашей помощи раньше - я могу запросить предметы с детьми:

$user->items()->whereNull('parent_id')->with('children')->get();

Это результат:

Illuminate\Database\Eloquent\Collection {#3247
 all: [
   App\Item {#3232
     id: 2,
     parent_id: null,
     title: "Parent 1",

     pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3235
       user_id: 12,
       user_item_id: 2,
       value: "3",
     },
     children: Illuminate\Database\Eloquent\Collection {#3267
       all: [
         App\Item {#3270
           id: 3,
           parent_id: 2,
           title: "Child 1",
           created_at: "2019-10-04 14:29:59",
           updated_at: "2019-10-04 14:29:59",
         },
         App\Item {#3272
           id: 4,
           parent_id: 2,
           title: "Child 2",
           created_at: "2019-10-04 14:30:16",
           updated_at: "2019-10-04 14:30:16",
         },
       ],
     },
   },
   App\Item {#3255
     id: 5,
     parent_id: null,
     title: "Parent 2",
     created_at: "2019-10-04 14:36:50",
     updated_at: "2019-10-04 14:36:50",
     pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3240
       user_id: 12,
       user_item_id: 5,
       value: "50",
     },
     children: Illuminate\Database\Eloquent\Collection {#3266
       all: [],
     },
   },
 ],
}

Как вы можетевидите, элементы parent получили значение сводки - у children нет данных сводки. Как я могу решить это? Я узнал, что hasMany не предоставляет сводку.

Мой вопрос

Как я могу добавить сводные данные к вложенному children в этом сценарии?

1 Ответ

2 голосов
/ 06 октября 2019

Как вы сказали, вы уже получаете пивот между вашим user и родителем item. Вот почему вы получаете атрибут pivot:

Illuminate\Database\Eloquent\Collection {#3247
 all: [
   App\Item {#3232
     id: 2,
     parent_id: null,
     title: "Parent 1", // <-----------

     pivot: Illuminate\Database\Eloquent\Relations\Pivot { /** ... */ }

Теперь вы стремитесь загрузить отношение children() запрашиваемого Items, это отношение hasMany, поэтому эти записи равнынет элемента сводки.

Если вам нужно вывести эти данные, вы можете просто показать родительскую запись для каждого дочернего элемента. Теперь, если вам действительно необходимо добавить родительские сводные данные в эти дочерние записи, вы можете реплицировать родительские данные, отображающие извлеченную коллекцию и добавив данные в каждый дочерний элемент:

$users = $user->items()->whereNull('parent_id')->with('children')->get();

$users = $users->map(function ($user) {
    $user->items->map(function ($parent) {
        $parent->children->map(function ($child) use ($parent) {
            $child->attribute = $parent->attribute;

            return $child;
        });

        return $parent;
    });

    return $user;
});

В этом примере сейчасу каждого ребенка Item будет скопирован родительский элемент attribute. Недостатком этого решения является то, что родительские данные будут такими же, как те, которые добавлены к дочерним данным, хотя я не знаю, является ли это желаемым результатом.

Кроме того, имейте в виду, что все этопроцесс выполняется в памяти, поэтому вы всегда должны контролировать количество извлекаемых данных, чтобы избежать проблем с памятью.

Другой альтернативой является непосредственное отношение дочерних элементов Items к объектам User. Таким образом, каждый дочерний элемент будет иметь свои собственные сводные данные, и вам не нужно будет загружать отношения children() на своих родителей Items. Конечно, вы можете сгруппировать их так, чтобы у вас была иерархия, соответствующая вашим потребностям, или просто различить родителей и их детей по значению parent_id.

...