为什么仅在Laravel Eloquent Builder中检查了范围的存在

时间:2018-06-21 07:24:05

标签: php laravel

翻阅Laravel的代码,我探索了我不完全了解的代码。

public function applyScopes()
{
    if (! $this->scopes) {
        return $this;
    }
    $builder = clone $this;
    foreach ($this->scopes as $identifier => $scope) {
        if (! isset($builder->scopes[$identifier])) {
            continue;
        }
        $builder->callScope(function (Builder $builder) use ($scope) {
            // If the scope is a Closure we will just go ahead and call the scope with the
            // builder instance. The "callScope" method will properly group the clauses
            // that are added to this query so "where" clauses maintain proper logic.
            if ($scope instanceof Closure) {
                $scope($builder);
            }
            // If the scope is a scope object, we will call the apply method on this scope
            // passing in the builder and the model instance. After we run all of these
            // scopes we will return back the builder instance to the outside caller.
            if ($scope instanceof Scope) {
                $scope->apply($builder, $this->getModel());
            }
        });
    }
    return $builder;
}

Source

this对象被克隆。该文档说,每个属性都是浅层克隆的,这意味着对其他对象的所有引用仍然存在。神奇的__clone只是query属性的例外,此处未使用。

为什么需要进行此检查:

    if (! isset($builder->scopes[$identifier])) {
        continue;
    }

thisbuilder是否应该定义相同的范围(甚至对它们的引用相同)?为什么还要麻烦检查呢?

为什么调用this->getModel()而不是builder.getModel()?只是因为它更短?

1 个答案:

答案 0 :(得分:1)

由于此Laravel使用git,因此您可以使用git blame来大致了解代码的用途以及原因,在检查完git怪之后,您可以看到与提交相关联的issue

该代码是作为问题19282的修复程序添加的,它允许用户使用另一个全局范围删除全局范围

用例:

  

假设我们有可以软删除的产品。   普通用户只能操作现有产品,但是特权较高的用户也可以操作已删除的产品。添加在某些情况下删除SoftDeletingScope的全局范围是行不通的-SoftDeletingScope被删除了,但也可以在之后立即应用。