如何在 Laravel 中为列表或数组定义策略?

Ric*_*ick 5 permissions authorization roles laravel laravel-passport

我有以下政策来确定用户是否能够查看合同。

public function view(User $user, Contract $contract)
    {
        if ($user->user_type->id == 2) { // If user is a vecino
            if ($user->id == $contract->customer_id) {
                return true;
            }
        } else if ($user->user_type->is_admin == true) { // If user is an admin
            return true;
        }

        return false;
    }
Run Code Online (Sandbox Code Playgroud)

然后检查授权

$this->authorize('view', $contract);
Run Code Online (Sandbox Code Playgroud)

如何检查列表/数组/集合的授权?就像我通过以下方式获得合同清单一样Contract::all()

我还没有找到任何方法来做到这一点。我可以做一个循环并为每次迭代调用 $this->authorize 来检查授权,但这可能会影响性能。

有没有更好的方法来做到这一点?

mrh*_*rhn 2

我在这种情况下经常看到的设计是检查是否允许通过策略查看查询中的所有元素。这不能很好地扩展并且分页效果不佳。

更好的解决方案不是过滤掉带有策略的合约,而是过滤查询中已有的合约。这主要是因为如果您想进行分页,您需要在执行查询之前进行所有过滤,以避免出现奇怪的分页元数据。同时还必须为每个元素运行 n 个操作,这对于 1000 个元素来说已经是一个问题。

执行以下查询子句,可以获得与您的策略相同的结果。

Contract::where('user_id', $user->id)->get();
Run Code Online (Sandbox Code Playgroud)

为了让自己的事情变得更容易,我通常做的一个版本是在用户模型中创建一个范围。

public function scopeOwned($query, User $user)
{
    return $this->query->where('user_id', $user->id);
}

Contract::owned($user)->get();
Run Code Online (Sandbox Code Playgroud)