0

I am querying a model using Laravel Eloquent. When there is records available the query returns a result that is an array of objects.

[{id: 2, num: 3}]

When there is no records available Eloquent returns an array within an array of objects where all the object properties has a null values.

[[{id: null, num: null}]]

The thing is how to I test whether there is no record or a null object. None of the following methods works:

isset($records) // does not cover empty object
!empty($records) // does not seem to see null properties
count($records) > 0 // sees an array more than zero deep

This is my query:

$records = FertilAppUser::select('fertilapp.*')
            ->leftJoin('fertilapp', 'fertilappuser.id', '=', 'fertilapp.fertilappuser_id')
            ->where('fertilappuser.id', '=', $request->get( 'id' ))
            ->groupBy('fertilapp.id')
            ->orderBy('fertilapp.id', 'asc')
            ->get();

An empty result must be handled because it is possible and it seems to be the one thing that is a pain to handle for me. Everything works, then I test empty results and boom comes errors!

Can someone help me to understand why the results are arrays of differing depths?

If both results where an array of objects it would be easy but how do I check for !empty($record[0]->id) and !empty($record[0][0]->id) without getting an error.

Interestingly the following query returns an array of objects or an array with null [null].

$records = DB::select('SELECT fertilapp.* ' .
                  ' FROM fertilapp ' .
                  ' LEFT JOIN fertilappuser ON fertilappuser.id = fertilapp.fertilappuser_id ' .
                  ' WHERE fertilappuser.id = ? ' .
                  ' GROUP BY fertilapp.id ' .
                  ' ORDER BY fertilapp.id ASC ', [$request->get( 'id' )]);

This can the be tested with above methods. Still would like to know why the Eloquent method is returning the result above.

After running the query I check if the results are usable and loop through them.

if (isset($records) && !empty($records) ) {                        
       foreach ($records as $key => $value) {...}
}
Hmerman6006
  • 1,622
  • 1
  • 20
  • 45
  • What are you doing with the `$record` after the query? Are you wrapping it in a `Resource` class? In any case, `$record` should be an `Eloquent Collection`. If you wannt to know if it's empty or not, use the collection methods: `$record->isEmpty()` or `$record->isNotEmpty()` – IGP Sep 08 '20 at 20:31
  • What do you mean resource class? – Hmerman6006 Sep 08 '20 at 20:34
  • Does using `->isEmpty()` / `->isNotEmpty()` return the expected values? And how are you 'testing' it? What are you using to dump the data and get an array within an array? – IGP Sep 08 '20 at 20:36
  • I mean an [Eloquent Resource](https://laravel.com/docs/7.x/eloquent-resources). If you're not using one it doesn't really matter. – IGP Sep 08 '20 at 20:38
  • I am using a model named `FertilAppUser`. – Hmerman6006 Sep 08 '20 at 20:40
  • But how are you viewing the data? What do you do with the $record variable? – IGP Sep 08 '20 at 20:41
  • I just added that part above. – Hmerman6006 Sep 08 '20 at 20:47
  • first, `isset($record)` will always return true since you're setting the `$record` variable yourself. Second, instead of `!empty($record)`, you should use either `!$record->isEmpty()` or `$record->isNotEmpty()`. Third, the null values you encounter are probably a result of the left join. Use an (inner) join if you want to avoid nulls. – IGP Sep 08 '20 at 21:02
  • You are correct! Thanks. If you make your comment the solution I will mark it as such. – Hmerman6006 Sep 08 '20 at 22:07

2 Answers2

1

First,

isset($record) will always return true since you're setting the $record variable yourself.

Second,

Instead of !empty($record), you should use either !$record->isEmpty() or $record->isNotEmpty().

Third,

The null values you encounter are probably a result of the left join. Use an (inner) join if you want to avoid null values.

IGP
  • 14,160
  • 4
  • 26
  • 43
0

You are using left join here - fertilappusers left join fertilapp It will return all users records even if they has no record in fertilapp table.

The queries you provided are different. The first one is like I said above. The second one is fertilapp left join fertilappusers which will give you all records from fertilapp even if there is no user for it.

Please check this link where you will get familiar how the mysql join works What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?

Emil Georgiev
  • 529
  • 4
  • 15