Intereting Posts
YouTube API v3 постоянно запрашивает авторизацию Как вставить значения из датпикера JQuery в формат даты в MySQL с помощью Codeigniter? Разрешить вход на веб-сайт только в том случае, если запрос поступает с другого конкретного веб-сайта PHP: Как проверить, правильно ли установлена ​​и включена ли библиотека? Бесплатная доставка в зависимости от веса и минимальной суммы MySQL возвращает первую строку объединенной таблицы отправить массив данных (одинаковые значения ключа), используя php curl Laravel – модельный класс не найден PHP mysql_insert_id () для первичных ключей UUID () MySQL? Будет ли PHP sha1 () и MySQL SHA () получить тот же результат? Подтвердите поле в привязке ссылок CodeIgniter для удаления записи Загрузить статус с PHP и JavaScript jQuery $ .ajax запрос dataType json не будет извлекать данные из скрипта PHP CakePHP и пространства имен? Преобразование целого числа в строку в PHP

Laravel ORM из таблицы саморегуляции получает N уровня иерархии JSON

Я использую LARAVEL 4 с MySQL back-end.

У меня есть таблица с self-referencing со столбцами id, name, type и parent . Здесь parent является foreign-key Id столбца. Данные в таблице приведены ниже:

 id name type parent 1 General group NULL 2 What is..? question 1 3 aa answer 2 4 bb answer 2 5 cc answer 2 6 How is..? question 1 7 ba answer 6 8 bb answer 6 9 Where is..? question 4 10 ca answer 9 11 cb answer 9 12 Who is..? question 6 13 da answer 12 14 db answer 12 15 Specific group NULL 16 When is..? question 15 17 ea answer 16 18 eb answer 16 19 Whome is..? question 2 20 fa answer 19 21 fb answer 19 22 fc answer 19 

Я хочу функцию, которая возвращает nested JSON используя эти реляционные данные. Например :

 [{ "id" : 1, "name" : "Geneal", "type" : "group", "children" : [{ "id" : 2, "name" : "What is..?", "type" : "question", "children" : [{ "id" : 3, "name" : "aa", "type" : "answer" }, { "id" : 4, "name" : "bb", "type" : "answer" }, { "id" : 5, "name" : "cc", "type" : "answer" }]}, { "id" : 6, "name" : "How is..?", "type" : "question", "children" : [{ "id" : 7, "name" : "ba", "type" : "answer" }, { "id" : 8, "name" : "bb", "type" : "answer" }] }] ... and so on }] 

Я создал model именем Survey как Survey ниже:

 class Survey extends BaseModel{ protected $table = 'questions'; protected $softDelete = false; public function parent() { return $this->belongsTo('Survey', 'parent'); } public function children() { return $this->hasMany('Survey', 'parent'); } } 

и назвал его controller :

 $user = Survey::all(); $parent = $user->parent()->first(); $children = $user->children()->get(); 

Но я не получаю должного результата, как я уже упоминал в JSON выше.

 print_r($parent->toJson()); 

дает записи только с одной иерархией уровней (т.е. группа и вопросы, а не ответы).

в то время как

 print_r($children ->toJson()); 

Дает только вопросы (не группы и ответы).

Я хочу, чтобы все данные саморегуляции в вложенном формате JSON с N уровнем иерархии .

Я также попробовал

 $user = Survey::with('parent', 'children')->get(); 

Но нашел то же самое, что и $ parent выше.

В любом случае, я могу получить желаемый результат?

Заранее спасибо..

Solutions Collecting From Web of "Laravel ORM из таблицы саморегуляции получает N уровня иерархии JSON"

Вот как вы вручную извлекаете вложенные отношения:

 $collection = Model::with('relation1.relation2.relation3')->get(); 

Поэтому в вашем случае это будет:

 $surveys = Survey::with('children.children.children')->get(); 

Очевидно, что это выполнит эту работу, когда отношения будут фиксированными, но это не путь для рекурсивного отношения к той же таблице.

К счастью, вы можете сделать такое отношение рекурсивным , тогда все, что вам нужно, чтобы получить цельное дерево:

 $surveys = Survey::with('childrenRecursive'); 

Тем не менее, я бы не загружал родителя для каждой строки таким образом.

Вот и все, что вам нужно:

 // Survey model // loads only direct children - 1 level public function children() { return $this->hasMany('Survey', 'parent'); } // recursive, loads all descendants public function childrenRecursive() { return $this->children()->with('childrenRecursive'); // which is equivalent to: // return $this->hasMany('Survey', 'parent')->with('childrenRecursive); } // parent public function parent() { return $this->belongsTo('Survey','parent'); } // all ascendants public function parentRecursive() { return $this->parent()->with('parentRecursive'); } 

EDIT: для получения реальной древовидной структуры первый запрос должен быть ограничен только корневыми узлами:

 $surveys = Survey::with('childrenRecursive')->whereNull('parent')->get(); 

так просто!!!

вам просто нужно добавить функцию clouser к вашим отношениям следующим образом:

 $surveys = Survey::with(['children' => function($q) { $q->with('children'); }, 'parent' => function($q) { $q->with('parent'); }); 

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

 $surveys->children 

и неограниченное гнездование:

 $surveys->children->first()->children 

и так далее.