我有这样的餐桌爱好:
-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 之外的所有爱好
所以我找到了一些方法来运行我想做的事情,但我不知道这是否是正确的方法:
// 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);
}
Hobbies::isNotLine('the-id-selected')->get();
结果我得到了所有的爱好,除了我选择的爱好,还有他的孩子和孙子