来自自引用表的Laravel ORM获得N级层次结构JSON

Dev*_*Dev 9 php laravel laravel-4

我使用LARAVEL 4MySQL后端.

我有一个self-referencingid, name, type和列表parent.这parentforeign-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
Run Code Online (Sandbox Code Playgroud)

我想要一个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
}]
Run Code Online (Sandbox Code Playgroud)

我创建了一个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');
    }   
}
Run Code Online (Sandbox Code Playgroud)

并称之为controller:

$user = Survey::all();
$parent = $user->parent()->first();
$children = $user->children()->get();
Run Code Online (Sandbox Code Playgroud)

但是我没有像JSON上面提到的那样得到正确的结果.

print_r($parent->toJson()); 
Run Code Online (Sandbox Code Playgroud)

仅给出一级层次结构的记录(即组和问题,而不是答案).

print_r($children ->toJson());
Run Code Online (Sandbox Code Playgroud)

只提出问题(不是小组和答案).

我希望嵌套的JSON格式的整个自引用数据具有N级层次结构.

我也试过了

$user = Survey::with('parent', 'children')->get();
Run Code Online (Sandbox Code Playgroud)

但发现与上面的$ parent相同.

无论如何我能得到想要的结果吗?

提前致谢..

Jar*_*zyk 46

以下是手动检索嵌套关系的方法:

$collection = Model::with('relation1.relation2.relation3')->get();
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下它将是:

$surveys = Survey::with('children.children.children')->get();
Run Code Online (Sandbox Code Playgroud)

显然,当关系修复时,这将完成工作,但这不是去同一个表的递归关系的方法.

幸运的是,你可以使这种关系递归,然后你需要检索整个树是这样的:

$surveys = Survey::with('childrenRecursive');
Run Code Online (Sandbox Code Playgroud)

但是,我不会以这种方式为每一行加载父级.

所以这就是你所需要的:

// 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');
}
Run Code Online (Sandbox Code Playgroud)

编辑:要获得真正的树结构,首先查询必须仅限于根节点:

$surveys = Survey::with('childrenRecursive')->whereNull('parent')->get();
Run Code Online (Sandbox Code Playgroud)