Выгрузка двумерного дерева (родитель-ребенок) из одной таблицы Laravel

Всем доброго дня. Возник вопрос такого рода: Как максимально правильно (хотелось бы в 1 запрос в БД) получить дерево родитель-ребенок из одной таблицы, где у ребенка в поле parent стоит id родителя, а у родителя NULL. И вообще вер но ли строить такие деревья в одной таблице, или лучше разнести на несколько и делать выборку отношениями?

введите сюда описание изображения

На выходе:

0 => [
   name => 'Имя 1'
   childs => [ 
      1 => [
           name => 'Имя ?'
      ],
      0 => [
           name => 'Имя ?'
      ]
   ]
]

Благодарю всех кто откликнется!


Ответы (2 шт):

Автор решения: Vladimir Gonchar

В Laravel правильным вариантом будет создать дерево через отношения. Не могу точно сказать, сколько запросов делает Laravel, но дерево Вы получите в точности как Вам надо.

Сама таблица у Вас сделана правильно (за исключением названия поля parent_id). Для получения дочерних элементов нужно в модели создать метод:

public function children() {
    return $this->hasMany(Self::class, 'parent_id')
                ->with('children');
}

Вызываете, соответственно, все значения верхнего уровня:

ModelName::whereParentId(null)->with('children')->get();
→ Ссылка
Автор решения: Zombotron

Помнится, приходилось мне строить дерево для 2-х разных сущностей (марка-модель- модификация и узел1-узел2-...-узелN) Там суммарно тысяч 10 записей было в 4-х таблицах и таблица связей модификаций с узлами (многие ко многим) где-то около 1М записей. Так в рантайме полностью все дерево "за полиноминальное время" не строилось. Ни фреймворком (yii), ни чистыми php и SQL-запросами. Пришлось подгружать xhr по мере надобности.

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

  • выбираю из бд все

  • перебираю в цикле, создаю массив:

    [ parent_id => array( array(name, id), array(name, id), ...),
    parent_id => array( array(name, id), array(name, id), ...),
    ...
    parent_id => array( array(name, id), array(name, id), ...) ]
    
  • потом, если не много уровней вложенности, рекурсивно строю часть DOM. Если много, но не очень, то в виде js массива или json на страницу и строить при помощи js итеративно сразу или по мере запроса.

В общем, реализация зависит от объема данных и от связей между этими данными.

→ Ссылка