【问题标题】:Laravel recursive where for recursive relationshipLaravel recursive where 递归关系
【发布时间】: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')->...
  • 我有无限的数据树,但我只给出了一部分数据,所以不值得这样使用
  • 它只是检索第一个层次结构,但我想检索除所选爱好以及他的孩子和孙子之外的所有内容

标签: laravel nested relationship


【解决方案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();

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

【讨论】:

    猜你喜欢
    • 2014-12-26
    • 1970-01-01
    • 2020-06-12
    • 2023-03-05
    • 2018-07-05
    • 2020-11-03
    • 2021-02-10
    • 2016-11-30
    • 2020-11-09
    相关资源
    最近更新 更多