Tolga
Tolga

Reputation: 282

CakePHP3 After removal of afterFind, where to check if query result empty?

Before i checked in the afterFind callback if the result of the find is empty. Since the callback was removed in latest versions, where would be the place to check that from a behavior?

Im not realy sure if that is what i need. My use case is, i want to find out if a query has no result. Then i would create a default entry so it has 1 result.

Upvotes: 5

Views: 1960

Answers (1)

floriank
floriank

Reputation: 25698

https://book.cakephp.org/3.0/en/appendices/orm-migration.html#no-afterfind-event-or-virtual-fields

Once defined you can access your new property using $user->full_name. Using the Modifying Results with Map/Reduce features of the ORM allow you to build aggregated data from your results, which is another use case that the afterFind callback was often used for.

Call count() on the ResultSet object

https://api.cakephp.org/3.4/class-Cake.ORM.ResultSet.html#_count

No idea why you're not using that and want to do the count manually, but go on.

Using resultFormatter()

https://book.cakephp.org/3.0/en/orm/query-builder.html#adding-calculated-fields

You behavior will have to add the formatter in your beforeFind() to the query. You can add a custom find that adds it as well. Example code (taken from the docs):

$query->formatResults(function (\Cake\Collection\CollectionInterface $results) {
    return $results->map(function ($row) {
        $row['age'] = $row['birth_date']->diff(new \DateTime)->y;
        return $row;
    });
});

Count the results there.

Using map/reduce

https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#map-reduce

More often than not, find operations require post-processing the data that is found in the database. While entities’ getter methods can take care of most of the virtual property generation or special data formatting, sometimes you need to change the data structure in a more fundamental way.

You behavior will have to add the mapper/reducer in your beforeFind() to the query. You can add a custom find that adds it as well. Example code (taken from the docs):

$articlesByStatus = $articles->find()
    ->where(['author_id' => 1])
    ->mapReduce($mapper, $reducer);

Check the above link for a detailed explanation including examples of how to create a mapper and reducer.

Upvotes: 4

Related Questions