Laravel 具有角色的控制器

Laravel controllers with roles

我有一个应用程序,它将是一个 SaaS 并且正在使用用户角色。当然,控制器需要根据用户角色或权限转发不同的数据,但我认为这种方法可能会导致我使用庞大的控制器,我想知道是否有更智能的方法来做到这一点?例如我的用户创建方法:

public function create()
{
    if (Auth::user()->isAdmin()) {
        $clinics = Clinic::pluck('name', 'id');
        $roles = Role::pluck('display_name', 'id');
    }
    else{
        $clinics = Clinic::where('id', Auth::user()->clinic_id)->get()->pluck('name', 'id');
        $roles = Role::where('name', '!=', 'admin')->get()->pluck('display_name', 'id');
    }

    $states = State::pluck('name', 'id');
    $cities = City::pluck('name', 'id');

    return view('users.create', compact('user', 'clinics', 'states', 'cities', 'roles'));
}

当我只实现管理员和非管理员用户时,现在还可以,但是当角色变得复杂时,有没有更简洁的方法来assemble?

我建议您查看 Laravel 文档的 Scopes。您可以将范围附加到您的模型以获得相同的结果。

此解决方案不会帮助您删除代码复杂性(在模型中移动),但会帮助您删除代码重复,因为您会在应用程序开发过程中多次遇到相同的 "if"...

您诊所的本地范围可能像这样

class Clinic extens Model {
    [...]
    public function scopeCanSee($query)
    {
        $user = Auth::user();
        if(!$user->isAdmin())
            return $query->where('id', $user->clinic_id);
        return $query;
    }
}

然后在您的控制器中,您可以用这种方式过滤结果

public function create()
{
    $clinics = Clinic::canSee()->pluck('name', 'id');
    [...]

    $states = State::pluck('name', 'id');
    $cities = City::pluck('name', 'id');

    return view('users.create', compact('user', 'clinics', 'states', 'cities', 'roles'));
}

全局范围

另一种方法是使用全局范围(但我还没有测试过)

class Role extends Model
{
    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new RolesScope);
    }
}
class Clinic extends Model
{
    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new ClinicsScope);
    }
}

和范围类似于

class ClinicsScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $user = Auth::user();
        $builder->where('id', $user->clinic_id);
    }
}