Intereting Posts
Debian: узнать об использовании процессора с помощью bash addAttributeToFilter и условие OR в коллекции Magento php тот же результат, добавляющий различное количество vars Задача cron для резервного копирования базы данных в linux / php Кодирование файлов cookie, чтобы их нельзя было подделать или читать и т. Д. php regex для удаления HTML AJAX / PHP – Как получить опубликованные данные для загрузки в модальный на той же странице Как визуализировать представление ZF2 в ответе JSON? Как однозначно идентифицировать компьютер? Как вы выполняете несколько операторов SQL в одной mysql_query? Фильтровать HTML на php PHP preg_split удаляет запятые и завершающий пробел Как получить фактический URL-адрес запроса в Apache / PHP, если он не существует, и пользователь перенаправляется на страницу ошибок 404? Как избежать повторной отправки данных при обновлении в php Как проверить, поддерживает ли curl для ssl?

Создатель запросов Laravel для рекурсивных результатов? Например, id, parent_id

Поэтому у меня есть данные, структурированные следующим образом:

id|parent_id|name 1 |null |foo 2 |1 |bar 3 |2 |baz 

Так что в основном foo->bar->baz . Я не понимаю, как использовать конструктор запросов laravel для получения строк для дочерней строки, а затем ее предков (до parent_id == null ). Можно ли это сделать с помощью laravel? Я провел небольшое исследование, и Postgres имеет RECURSIVE то время как MySQL не выполняет ( рекурсивный запрос Postgres для обновления значений поля при перемещении parent_id ).

Я считаю, что MySQL имеет нечто похожее: как выполнить рекурсивный запрос SELECT в MySQL?

Но как бы реализовать это в Laravel?

Мой начальный код в основном использует область запроса, но я просто не понимаю:

 Model::select('name')->getParent(3); //get baz and the ancestors of baz protected function scopeGetParent($id) { $parent = Model::where('id', '=', $id); return $query->getParent($parent->parent_id); } 

Желаемый результат:

 name baz bar foo 

Есть идеи?

Итак, после использования метода merge() для класса Collections :

 public static function ancestors($id) { $ancestors = Model::where('id', '=', $id)->get(); while ($ancestors->last()->parent_id !== null) { $parent = Model::where('id', '=', $ancestors->last()->parent_id)->get(); $ancestors = $ancestors->merge($parent); } return $ancestors; } 

Это даст то, что мне нужно, но я считаю, что он может быть более чистым, поэтому, пожалуйста, не стесняйтесь его редактировать!

Я изменил решение tiffanyhwang и превратил его в нестатический метод и включил атрибут accessor, чтобы упростить получение результатов.

 public function ancestors() { $ancestors = $this->where('id', '=', $this->parent_id)->get(); while ($ancestors->last() && $ancestors->last()->parent_id !== null) { $parent = $this->where('id', '=', $ancestors->last()->parent_id)->get(); $ancestors = $ancestors->merge($parent); } return $ancestors; } 

и аксессуар для извлечения коллекции предков из атрибута модели

 public function getAncestorsAttribute() { return $this->ancestors(); // or like this, if you want it the other way around // return $this->ancestors()->reverse(); } 

так что теперь вы можете получить таких предков:

 $ancestors = $model->ancestors; 

и с момента его создания вы можете теперь легко сделать это:

 echo $model->ancestors->implode('title',', '); 

Другим способом может быть использование пакета etrepat / baum , это реализация Laravel модели вложенного набора . Он использует упорядоченное дерево, которое работает быстрее и использует нерекурсивные запросы. Хотя ваши данные структурированы следующим образом:

 root |_ Child 1 |_ Child 1.1 |_ Child 1.2 |_ Child 2 |_ Child 2.1 |_ Child 2.2 

Структурированные таким образом в модели с вложенными наборами:

  ___________________________________________________________________ | Root | | ____________________________ ____________________________ | | | Child 1 | | Child 2 | | | | __________ _________ | | __________ _________ | | | | | C 1.1 | | C 1.2 | | | | C 2.1 | | C 2.2 | | | 1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14 | |___________________________| |___________________________| | |___________________________________________________________________| 

Вставка узлов проста:

 $child1 = $root->children()->create(['name' => 'Child 1']);