Home > Software engineering >  Eloquent count of single object is wrong
Eloquent count of single object is wrong

Time:08-10

I have a method that only changes one small thing based on if an object of one item is passed through, vs a single object, but the count() is wrong on single items...

Assuming I have 25 entries in my table...

$contacts = Contact::all();
dd("Count = " . $contacts->count());

Count = 25

$contact = Contact::where('individual_id', '=', $id)->first();
dd("Count = " . $contact->count());

Count = 25

Why is it showing a count of objects in the table instead of just the number that were returned?

  • Laravel v9.19
  • PHP v8.0.2

CodePudding user response:

Let's analyze your code:

$contact = Contact::where('individual_id', '=', $id)->first();

$contact will either be an instance of your Contact model, or null.

If it is a Model instance, then calling ->count() is basically calling this:

Contact::count(); // 25

$contact = Contact::where('individual_id', '=', $id)->first();
$contact->count() == Contact::count(); // true

Models have a count() method, so you can do things like $model->where(...)->count(), etc.

If $contact is null, then your code will fail:

$contact = null;
$contact->count(); // Error: `null->count()` is invalid.

So, for your case, there is basically no reason to ever call Contact::where(...)->first()->count(), as that will not return 1, unless there is legitimately 1 record in your contacts table (pretty scary false-positive).

The other answer suggests to use ->get(), which is valid, as a Collection has a count() method that outputs the length of the underlying Array:

$contact = Contact::where('individual_id', '=', $id)->get();
$contact->count(); // 1

It will return 1, unless you have multiple records in the database where individual_id is equal to $id.

So, TL;DR: ->first() returns a single Contact instance or null and shouldn't use ->count() after, while ::all() or ->get() returns multiple and can use ->count() after.

CodePudding user response:

When you are using first() it is returning MODEL.You have to use get() so that you can use count() as get() will return collection.

$contact = Contact::where('individual_id', '=', $id)->get();
dd("Count = " . $contact->count());

It will give you the desired result.

also you can do this...

$count = Contact::where('individual_id', '=', $id)->count();
dd("Count = " . $count);
  • Related