Model::count() returns error in Query scope

I am using count() method to count rows in a model. It works if i use it directly like this:

return Model::count();

But when I try to use it from Query scope, I am getting an error:

Object of class Illuminate\Database\Eloquent\Builder could not be converted to string

Query scope in Model:

public function scopecountUsers($query) {
    return $query->count();
}

Can anyone explain why it is so?

There are no rows in the table.

Answers


The reason you are getting this error is the way scopes are handled in Eloquent builder. If you have a look at the Builder's code, you can see the following method:

protected function callScope($scope, $parameters)
{
    array_unshift($parameters, $this);
    return call_user_func_array([$this->model, $scope], $parameters) ?: $this;
}

As you can see, if the scope method returns a truthy value (a value that evaluates to true when cast to boolean), then this value is a result of calling the scope. On the other hand, if the returned value evaluates to false, the builder object is returned instead. In your case, as you have no rows in the table, scope's return value is 0, that's why you're getting the builder object as a result of Model::countUsers().

If you cannot guarantee that a scope will always return a truthy value, it's not a good idea to return anything from the scope method. My suggestion is to use scopes only to define common sets of constraints that you may easily re-use throughout your application, as the documentation suggests, not to execute queries. Some examples:

Model::someScope()->get();
Model::someScope()->someOtherScope()->count();

Need Your Help

Cannot declare private variables in constructor?

java constructor

I'm programming in Java and I'm having trouble getting the following code to compile. The error (illegal start of expression) shows up at

How to subclass an UIButton to pass multiple NSString parameters via addTarget:action:forControlEvents

parameters uibutton nsstring action addtarget

I have to programmatically define (without using any IBAction) a UIButton that when tapped gets the values of 3 NSString parameters and executes a Segue.