从多个关系生成层次结构

Ken*_*rna 5 php tree nested hierarchy laravel

我无法从API消耗的数据生成层次结构.

此时,两个模型之间存在多对多的关系:Tags和Nodes.

现在,我需要的是parent_idTag模型上设置一个知道哪个Tag是它的父级.这将是递归的,因为有几个深度级别.

问题在于,这个过程需要从多对多关系的实际数据中加以阐述.所以我一直在玩集合(Node::all()/ Tag::all())来尝试创建这个结构,然后在子标签中批量分配父标签的ID.

我的想法是从Nodes 加载标记,然后在集合中为节点的每个标记子项创建一个新项

所以这:

|
|__Node A
|  |__Tag 1
|  |__Tag 2
|  |__Tag 3
|
|__Node B
|  |__Tag 1
|  |__Tag 3
|  
|__Node c
   |__Tag 1
   |__Tag 2
Run Code Online (Sandbox Code Playgroud)

可以转换为这个(我知道每个项目都需要一个唯一的密钥,我正在考虑分配一个临时密钥):

|
|__Node A
|  |__Tag 1
|
|__Node A
|  |__Tag 2
|
|__Node A
|  |__Tag 3
|
|__Node B
|  |__Tag 1
|
|__Node B
|  |__Tag 3
|  
|__Node c
|  |__Tag 1
|  
|__Node c
   |__Tag 2
Run Code Online (Sandbox Code Playgroud)

然后我可以将(通过递归)分组标记密钥分组为:

|__Tag 1
   |
   |__Tag 2
   |  |
   |  |__Node A
   |  |__Node C
   |
   |__Tag 3
      |
      |__Node A
      |__Node B
Run Code Online (Sandbox Code Playgroud)

我的问题是,不知道(还)如何正确地进行这种转换.

Sae*_*.Gh 1

使用最佳实践

首先,我建议您看一下这个教程。作为使用权重制作层次结构数据的最佳实践。

使用雄辩

当你使用 Laravel 雄辩关系作为它的活动记录时

//in Tag Model
public function children()
{
    return $this->hasMany('App\Models\Tag', 'parent_id');   
}

public function parent(){
     return $this->belongsTo('App\Models\Tag', 'parent_id');
}

public function nodes()
{
    return $this->hasMany('App\Models\Node', 'node_id', 'node_id');   
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以得到结果

//there should be a relation for node also 
Tag::with('parent', 'children.children', 'node')->get();
Run Code Online (Sandbox Code Playgroud)

一个简单的php方式

而且我认为这是一个简单的方法:

foreach ($tags as $key => $value) {
    $tagTree[$value['tag_id']] = $value;
    $tagTree[$value['tag_id']]['child'] = array();
}

foreach ($tagTree as $key => $value) {
    if ($value['parent_id'] == 0) {
        $root[$key] = &$tagTree[$key];
    } else {
        $tagTree[$value['parent_id']]['child'][$key] = &$tagTree[$key];
    }

    //here you can check if is there any node for current tag insert 
    //$tagTree[$value['parent_id']]['node'][] = ...
}
Run Code Online (Sandbox Code Playgroud)