Laravel:创建一个虚假的BelongToMany与Pivot关系



我在UserGroup之间有一个belongsToMany()关系。用户在其所属的任何组中都有一个level

public function groups()
{
return $this->belongsToMany('AppGroup', 'user_group', 'user_id', 'group_id')
->withPivot('level');
}

这很管用。

但是,如果User是管理员,我希望groups函数返回带有level = 3的所有Group,而不管透视表中是否存在这种关系。

我可以成功创建一个Collection,它镜像了如下数据结构:

AppGroup::all()->transform(function ($item, $key) use ($uid) {
$item->pivot = collect(['user_id'=>$uid,'group_id'=>$item->id,'level'=>3]);
return $item;
});

但是,我不能替换这两个输出,因为一个返回belongsTo关系实例,另一个返回一个Collection。这意味着我可以在前者上调用->get(),但不能在后者上调用。

我考虑过使用DB::立面并为后者创建Builder,但我无法手动添加Pivot值。

对如何实现这一目标有什么想法吗?

--更新--

我目前通过在groups()方法中添加->get()来作弊,但这很混乱,我仍然想知道是否有更好的方法来解决这个问题。

public function groups()
{
if ($this->isAdmin()) {
return AppGroup::all()->transform(function ($item, $key) use ($uid) {
$item->pivot = collect(['user_id'=>$uid,'group_id'=>$item->id,'level'=>3]);
return $item;
});
} else { 
return $this->belongsToMany('AppGroup', 'user_group', 'user_id', 'group_id')
->withPivot('level')->get();
}
}

所以这个解决方案应该可以工作(没有经过测试(,但它不是"最干净的"——最好通过其他机制访问所有组,但因为我不知道你的管理实现,所以很难猜测。

public function groups()
{
return $this->belongsToMany('AppGroup', 'user_group', 'user_id', 'group_id')
->withPivot('level');
}
public function scopeSpecialGroups($query)
{
return $query->when($this->role === 'admin',function($query){
return Group::where('level', '>', 3');
})->when($this->role != 'admin',function($query){
return $query->with('groups');
});
}

然后您应该能够呼叫User::specialGroups()->get();

最新更新