我在User
和Group
之间有一个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();