来自自引用表的 Laravel ORM 获得 N 级层次结构 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24672629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel ORM from self referencing table get N level hierarchy JSON
提问by Dev
I am using LARAVEL 4
with MySQL
back-end.
我使用LARAVEL 4
与MySQL
后端。
I have a self-referencing
table with columns id, name, type
and parent
.
Here, parent
is foreign-key
of the column Id
. The data in table is as below :
我有一个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
I want a function that return nested JSON
using this relational data. For example :
我想要一个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
}]
I have created a model
named Survey
as below :
我创建了一个model
命名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');
}
}
and called it in controller
with :
并调用它controller
:
$user = Survey::all();
$parent = $user->parent()->first();
$children = $user->children()->get();
But I am not getting the proper result as I have mentioned in JSON
above.
但是我没有得到JSON
上面提到的正确结果。
print_r($parent->toJson());
gives records with one level hierarchy only (i.e group and questions, not answers).
仅提供具有一级层次结构的记录(即组和问题,而不是答案)。
while
尽管
print_r($children ->toJson());
Gives only questions (Not groups and answers).
只给出问题(不是分组和答案)。
I want the whole self-referencing data in nested JSON format with N level of hierarchy.
我想要嵌套 JSON 格式的整个自引用数据,具有 N 级层次结构。
I also have tried
我也试过
$user = Survey::with('parent', 'children')->get();
But found same as $parent above.
但发现与上面的 $parent 相同。
Is there anyway I can get the desired result?
无论如何我能得到想要的结果吗?
Thanks in advance..
提前致谢..
回答by Jarek Tkaczyk
Here's how you manually retrieve nested relations:
以下是手动检索嵌套关系的方法:
$collection = Model::with('relation1.relation2.relation3')->get();
So in your case it would be:
所以在你的情况下,它将是:
$surveys = Survey::with('children.children.children')->get();
Obviously this will do the job when the relations are fixed, but it's not the way to go for a recursive relation to the same table.
显然,当关系固定时,这将完成工作,但这不是对同一张表建立递归关系的方法。
Fortunately, you can make such relation recursive, then all you need to retrieve whole tree is this:
幸运的是,你可以使这种关系递归,那么你需要检索整个树是这样的:
$surveys = Survey::with('childrenRecursive');
However, I wouldn't load parent for each row this way.
但是,我不会以这种方式为每一行加载父级。
So here's all you need:
所以这就是你所需要的:
// 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: To get real tree structure, first query must be limited to only root nodes:
编辑:要获得真正的树结构,第一次查询必须仅限于根节点:
$surveys = Survey::with('childrenRecursive')->whereNull('parent')->get();
回答by ??????? ????
so simple!!!
很简单!!!
1- load your 'children' relation in your 'children' relation in your model like this :
1- 像这样在模型中的“孩子”关系中加载“孩子”关系:
class Survey extends BaseModel{
protected $table = 'questions';
protected $softDelete = false;
public function parent()
{
return $this->belongsTo('Survey', 'parent');
}
public function children()
{
// change this: return $this->hasMany('Survey', 'parent');
return $this->hasMany('Survey', 'parent')->with('children);
}
}
2- you just need add clouserfunction to your relation like this:
2- 你只需要像这样向你的关系添加clouser函数:
$surveys = Survey::with(['children' => function($q) {
$q->with('children');
},
'parent' => function($q) {
$q->with('parent');
});
then you can access to your nested children in your result like this:
然后您可以像这样访问结果中的嵌套子项:
$surveys->children
and unlimited nesting :
和无限嵌套:
$surveys->children->first()->children
and so on.
等等。