Laravel 递归 where 表示递归关系

问题描述 投票:0回答:1

我有这样的餐桌爱好:

-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 之外的所有爱好

php laravel recursion nested relationship
1个回答
0
投票

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

 // 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 将结果转换为展平数组(列出所有没有嵌套关系的数组)
  • 第三次我再次转换成 id 数组
  • 第四,我在 whereNotIn 中使用这个数组来检索所有爱好并排除所选的爱好及其子行
  • 第五,我使用了我的瞄准镜,如
    Hobbies::isNotLine('the-id-selected')->get();

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

© www.soinside.com 2019 - 2024. All rights reserved.