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

时间:2014-07-10 09:13:42

标签: php laravel laravel-4

我正在使用LARAVEL 4后端MySQL

我有一个self-referencing表,其中包含id, 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

我想要一个使用此关系数据返回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的{​​{1}},如下所示:

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()); 

仅提出问题(不是小组和答案)。

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

我也试过

print_r($children ->toJson());

但与上面的$ parent相同。

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

提前致谢..

2 个答案:

答案 0 :(得分:41)

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

$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');
}

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

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

答案 1 :(得分:2)

这么简单!!!

1-加载您的孩子'你孩子的关系'模型中的关系如下:

$.ajax({
  type: "POST",
  url: "send.php",
  data: "name=" + <?php echo $_GET['name']; ?>, 
  success: function(data) {
    $("#div").html(data();
  }
});

2-您只需要将 clouser 功能添加到您的关系中:

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);
    }   
}

然后您可以像这样访问结果中的嵌套子项:

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

和无限嵌套:

$surveys->children

等等。