删除SoftDeletingScope作为全局范围

时间:2017-02-23 09:15:34

标签: php laravel laravel-5.4

我正在尝试删除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被调用,但之前没有被调用(确切地说,方法没有删除users.deleted_at is null部分。我分开试了一下,然后一起试了。

我知道我可以做类似$users = User::withTrashed()->get();这样的工作,但这并不完全安全,因为我必须找到可以查询用户的每个位置并将其包装在if语句中。< / p>

2 个答案:

答案 0 :(得分:1)

我不知道如何从SoftDeletes trait中覆盖bootSoftDeletes()更简单的解决方案:

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

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

答案 1 :(得分:0)

此解决方案根据条件删除范围。防止调用未定义的方法错误,这些错误是我使用接受的答案得到的。

<?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);
    }
}

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