On a User model (table with 4 records), when I do:
$coll = User::all();
echo $coll->count();
I get the amount of records found (4).
But when I do:
$coll = User::find(2);
echo $coll->count();
I do not get 1 (As I expect) but the amount of attributes in the resulting collection (23 in this case).
How can I check if more then one records are found?
UPDATE:
OK, thanks to you all I now see the difference in result between collection and model.
But my real problem is that I have to detect if I am having a model or a collection as a result. Depending on this result I perform some changes on the contents of the fields in the items (with map()) or model. How can I detect if the result is a model or a collection?
if(count($coll) > 1)
Works, but is this the right approach?
Here's what's going on with the code you have there:
1. When calling User::all()
you'll get a Illuminate\Database\Eloquent\Collection
on which you can call count
which counts the elements in the collection like so:
public function count()
{
return count($this->items);
}
This will return the number of items in the collection as you correctly expected.
2. When calling User::find(2)
however, the Eloquent Query Builder will not return a Collection
, because it will check to see how many results there are, and since you passed one ID you'll get at most one result, so it will return an Eloquent Model instead. The Model does not have a count()
method, so when you try to call $coll->count();
it will go to the magic __call
method that the class has implemented which looks like this:
public function __call($method, $parameters)
{
if (in_array($method, array('increment', 'decrement')))
{
return call_user_func_array(array($this, $method), $parameters);
}
$query = $this->newQuery();
return call_user_func_array(array($query, $method), $parameters);
}
As you can see the method tries to see if it should call a couple of hardcoded methods (increment
and decrement
), which of course don't match in this case because $method = 'count'
, so it continues to create a new Query on which it will call the count
method.
The bottom line is that both the first and second code samples end up doing the same thing: counting all the entries in the users
table.
And since, as I pointed our above, one ID cannot match more than one row (since IDs are unique), the answer to your question is that there's no need or way to count the results of find(2)
, since it can only be 0 (if null
is returned) or 1 (if a Model
is returned).
UPDATE
First of all, for future reference you can use the PHP get_class
to determine the class name of an object or get_parent_class
to determine the class it is extending. In your case the second function get_parent_class
might be useful for determining the model class since the User
class extends a Laravel abstract Model class.
So if you have a model get_class($coll)
will report User
, but get_parent_class($coll)
will report \Illuminate\Database\Eloquent\Model
.
Now to check if the result is a Collection or a Model you can use instanceof
:
instanceof
is used to determine whether a PHP variable is an instantiated object of a certain class
Your checks should look something like this:
// Check if it's a Collection
if ($coll instanceof \Illuminate\Support\Collection)
// Check if it's a Model
if ($coll instanceof \Illuminate\Database\Eloquent\Model)
You might also want to check if the result is null
, since find
will return null
if no entry is found with the given ID:
if (is_null($coll))
It seems you are expecting the find()-method to behave differently. From the docs
Find a model by its primary key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With