从多对多关系生成层次结构

时间:2019-02-15 16:16:11

标签: php laravel tree nested hierarchy

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

此刻,两个模型TagNode之间存在多对多的关系。

现在,我需要在parent_id模型上设置一个Tag,以知道哪个Tag是其父级。这将是递归的,因为深度有多个级别。

问题是,需要从多对多关系的实际数据中详细说明此过程。因此,我一直在尝试使用集合(Node::all() / Tag::all())来尝试创建此结构,然后在子标记中将父标记的ID大量分配。

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

所以这个:

|
|__Node A
|  |__Tag 1
|  |__Tag 2
|  |__Tag 3
|
|__Node B
|  |__Tag 1
|  |__Tag 3
|  
|__Node c
   |__Tag 1
   |__Tag 2

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

|
|__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

然后,我可以(递归地)将标签键分组为:

|__Tag 1
   |
   |__Tag 2
   |  |
   |  |__Node A
   |  |__Node C
   |
   |__Tag 3
      |
      |__Node A
      |__Node B

我的问题是,尚不知道如何正确进行此转换。

1 个答案:

答案 0 :(得分:1)

使用最佳做法

首先,我建议您看看this的toturial。作为使用权重制作层次结构数据的最佳实践。

使用口才

以及您使用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');   
}

然后您可以得到结果

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

一种简单的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'][] = ...
}