删除 SoftDeletingScope 作为全局范围

Remove SoftDeletingScope as global scope

我正在尝试删除 SoftDeletingScope 作为特定用户角色的全局范围。所以它应该看起来像这样:

protected static function boot()
{
    parent::boot();

    if (Auth::check()) {
        // CPOs can see deleted users
        if (Auth::user()->hasRole('cpo')) {
            static::addGlobalScope('user-cpo-deleted', function(Builder $builder) {
                // 1
                $builder->withoutGlobalScope(Illuminate\Database\Eloquent\SoftDeletingScope::class);
                // 2
                $builder->withoutGlobalScopes();
                // 3
                $builder->withTrashed();
                // 4
                $builder->where('id', '>=', 1);
            });
        }
    }
}

我尝试了解决方案 1-3,并且为了确保调用了方法 4。我记录了 SQL 查询并看到调用了 4,但没有调用之前的 3(准确地说,这些方法没有删除 users.deleted_at is null 部分)。我分别试过,也试过一起试。

我知道我可以做这样的事情 $users = User::withTrashed()->get();,这是有效的,但是这并不完全安全,因为我必须找到可以查询用户的每个位置并将其包装在 if 语句中.

我不知道有什么比从 SoftDeletes 特征覆盖 bootSoftDeletes() 更简单的解决方案了:

public static function bootSoftDeletes()
{
    if (!Auth::check() || !Auth::user()->hasRole('cpo')) {
        static::addGlobalScope(new SoftDeletingScope);
    }
}

动态添加和删除全局范围有时会产生一些奇怪的行为:/

此解决方案根据条件删除范围。防止使用已接受的答案调用未定义的方法错误。

<?php namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\SoftDeletingScope;

/**
 * Class UserScope
 *
 * @package App\Scopes
 */
class UserScope implements Scope
{
    /**
     * @param Builder $builder
     * @param Model   $model
     */
    public function apply(Builder $builder, Model $model)
    {
        if (optional(auth()->user())->is_admin) $builder->withoutGlobalScope(SoftDeletingScope::class);
    }
}

为了让它工作,我必须确保在调用模型父引导方法之前添加范围。