Сначала я собираюсь ответить на ваш вопрос, но во второй половине ответа я предложил альтернативу, которую я настоятельно рекомендую принять.
MySQL (в отличие, кстати, отMicrosoft SQL) не имеет возможности писать рекурсивные запросы.Соответственно, нет хороших отношений Laravel для моделирования этого.
Таким образом, у Laravel нет никакого способа сделать это, кроме как наивно, что, если у вас сложное дерево, приведет к множеству запросов.,
По сути, когда вы загружаете своего родителя, у вас будет доступ только к его дочерним элементам (как к коллекции отношений).Затем вы бы foreach
через его потомков (а затем и их потомков и т. Д., Рекурсивно) сгенерировали все дерево.Каждый раз, когда вы делаете это, он выполняет новые запросы для дочернего элемента и его дочерних элементов.По сути, это то, чем вы сейчас занимаетесь, и вы обнаружите, что по мере роста вашего набора данных он станет очень медленным.В конце концов, это предоставляет вам структуру данных, к которой вы можете применять свои фильтры и условия в коде. Вы не сможете достичь этого за один запрос.
Если вы много пишете в БД, то есть добавляете много новых детей, но редко читаете результаты, тогда это можетбыть вашим лучшим решением.
(Редактировать: приведенный ниже комментарий abr связал меня с примечаниями к выпуску MySQL 8, которые имеет , имеют эту функциональность. Мой первоначальный ответ был основан на MySQL 5.7.Я не знаю, что у Laravel / Eloquent есть решение для канонических отношений, использующее это. Более того, я ранее использовал эту функциональность в MSSQL, а вложенные множества являются лучшим решением IMO.
Кроме того, Laravel не обязательно связан сMySQL - это просто часто выбираемая база данных. Поэтому он, вероятно, никогда не будет использовать такое конкретное решение, чтобы избежать такой тесной связи.)
Однако большинство иерархических структур читают больше, чем пишут, и в этом случаеэто приведет к значительной нагрузке на ваш сервер.
Если это так, я бытиски:
https://en.wikipedia.org/wiki/Nested_set_model
Мы используем https://github.com/lazychaser/laravel-nestedset, который является реализацией вышеупомянутого, и он очень хорошо работает для нас.
ЭтоСтоит отметить, что это может быть медленным и занимать много памяти, когда мы переопределяем все дерево (у нас около 20 000 родительско-дочерних отношений), но это должно произойти только тогда, когда мы допустили ошибку в иерархии, которая не может быть выбранавручную, и это редко (мы не делали это в течение 6 месяцев).Опять же, если вы считаете, что вам, возможно, придется делать это регулярно, это может оказаться не лучшим вариантом для вас.