代码之家  ›  专栏  ›  技术社区  ›  Kenny Horna

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

  •  0
  • Kenny Horna  · 技术社区  · 5 年前

    我很难从API消耗的数据生成层次结构。

    目前,两种模式之间存在着多对多的关系: Tag s和 Node

    现在,我需要的是 parent_id 模型知道 标签 是它的父母。这将是递归的,因为有几个层次的深度。

    问题是,这个过程需要从多对多关系的实际数据进行详细说明。所以我一直在玩收藏品( Node::all() / Tag::all()

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

    所以这个:

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

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

    0 回复  |  直到 5 年前
        1
  •  1
  •   Saeed.Gh    5 年前

    使用最佳实践

    首先我建议你看看 this 托图里尔。作为使用权重生成层次结构数据的最佳实践。

    而且你用拉维雄辩的关系作为它的活跃记录

    //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'][] = ...
    }