Laravel recursive where 递归关系

Posted

技术标签:

【中文标题】Laravel recursive where 递归关系【英文标题】:Laravel recursive where for recursive relationship 【发布时间】:2022-01-21 23:03:14 【问题描述】:

我有这样的餐桌爱好:

-id
-name
-parent_id

还有我的模特

public function sub_hobbies()
    return $this->hasMany(Hobbies::class, 'parent_id');


public function parent_hobbies()
    return $this->belongsTo(Hobbies::class, 'parent_id');


public function allsub()
    return $this->sub_hobbies()->with('allsub');


public function allparent()
    return $this->parent_hobbies()->with('allparent');

我想要的是获得不是既定爱好的孩子或孙子的所有爱好

例如我有这个列表:

-hobbies 1
  -hobbies 11
  -hobbies 12
    -hobbies 121
    -hobbies 122
  -hobbies 13
-hobbies 2
  -hobbies 21
  -hobbies 22
    -hobbies 221
    -hobbies 222
  -hobbies 23
-hobbies 3
  -hobbies 31
  -hobbies 32
    -hobbies 321
    -hobbies 322
  -hobbies 33

如果我给出爱好 1 的 id,我想要除爱好 11、12、121、122、13 之外的所有爱好

【问题讨论】:

Hobby::doesntHave('parent_hobbies')->orDoesntHave('parent_hobbies.parent_hobbies')->... 我有无限的数据树,但我只给出了一部分数据,所以不值得这样使用 它只是检索第一个层次结构,但我想检索除所选爱好以及他的孩子和孙子之外的所有内容 【参考方案1】:

所以我找到了一个小方法来做我想做的事情,但我不知道这是否是正确的方法:

 // get hobbies and exlude given hobbies and his child line
    public function scopeIsNotLine($query, $id)
        // get all hobbies to exclude by id and his child line
        $hobbies = Hobbies::with('allsub')->where('id', $id)->get()->toArray(); 

        // transform result to array of id of hobbies to exclude
        $exclude = collect($this->flatten($hobbies))->map(function ($item) 
            return collect($item)
                ->only(['id'])
                ->all();
        )->flatten()->all();

        // get hobbies where id not in exluded hobbies
        return $query->whereNotIn('id', $exclude)->whereDoesntHave('is_archive');
    

    // transform nested result to simple array without nest hierarchie
    private function flatten($array) 
        $result = [];
        foreach ($array as $item) 
            if (is_array($item)) 
                $result[] = array_filter($item, function($array) 
                    return ! is_array($array);
                );
                $result = array_merge($result, $this->flatten($item));
            
        
        return array_filter($result);
    
首先我检索了他所有的孩子和孙子选择的爱好 其次,我使用我创建的函数 flatten 将结果转换为扁平数组(列出所有没有嵌套关系) 第三个 i 再次转换为 id 数组 第四,我在 whereNotIn 中使用这个数组来检索所有的爱好并排除选择的爱好和他的子行 第五次我使用了我的范围,比如Hobbies::isNotLine('the-id-selected')->get();

结果我得到了所有的爱好,除了我选择的爱好,还有他的孩子和孙子

【讨论】:

以上是关于Laravel recursive where 递归关系的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5950 Recursive sequence 矩阵快速幂

Laravel JsonResource:array_merge_recursive():参数 #2 不是数组

数据结构与算法—递归recursion

CF1106F Lunar New Year and a Recursive Sequence 原根矩阵快速幂高次剩余BSGS

[HDOJ5950]Recursive sequence(递推,二项展开,矩阵快速幂)

CF1106F Lunar New Year and a Recursive Sequence