1

I made a scope which ends up somehow in an endless loop. While simplifying it to the minimal reproducible example I came to this:

public function apply(Builder $builder, Model $model)
{
    Log::info('[Search] SQL: ' . $builder->toSql() . " Bindings: " . implode(', ', $builder->getBindings()));
}

The scope is implemented in the model in the standard way:

protected static function booted()
{
    static::addGlobalScope(new AuthorizationScope());
}

If I run the code like this, I end up on the following error:

Maximum function nesting level of '256' reached, aborting!

Why is it impossible to get the SQL dump within the scope itself? Can this be amended somehow? Options like enabling the DB query log on other places are not really part of this question.

Norgul
  • 4,613
  • 13
  • 61
  • 144
  • Aren't global scopes applied at the time the SQL is build? Your `toSql` simply activates a recursive call, calling the scope functions again and again. – Maarten Veerman Jul 19 '20 at 08:25
  • Probably yes. So I guess there is no way to print it out unless on the query end? – Norgul Jul 19 '20 at 09:09
  • Apparently. Maybe dig into the Builder class a bit. I believe there's a `baseQuery` function, maybe it works with that. (Cannot check it right now). I'm actually not sure what you are trying to achieve. You create a log because you want to investigate something, but what do you want to check? – Maarten Veerman Jul 19 '20 at 09:15

1 Answers1

0

Digging deeper as Maarten suggested led me to answer that this is indeed a recursive call.

Since toSql() is not an Eloquent\Builder method, but a Query\Builder one, it get's forwarded though __call() magic method which in this case needs to get a query builder instance applying the scopes before it actually executes the scope:

public function toBase()
{
    return $this->applyScopes()->getQuery();
}

Further down the line, apply scopes calls the apply() method which returns to my code which again triggers the same thing over and over again:

if ($scope instanceof Scope) {
    $scope->apply($builder, $this->getModel());
}

So answering my own question, it is not possible to do what I wanted because of the following.

Norgul
  • 4,613
  • 13
  • 61
  • 144