CakePhp 4 - contain array of ids

I’m trying to write a query with a contained relation and want to format the result.

Example:
There’s an Author that hasMany Books.
Now I want to find the author and contain his book-IDs.

The result format I want is:

$author = [
 id,
 firstname,
 lastname,
 books: [1,5,18,21]
]

I’m struggling how to write the query.
Here’s what I tried (not working)

$this->Authors->findById(id)->contain([
     'Books' => function (Query $q) {
           return $q->formatResults(function ($results) {
                return $results->reduce(function($acc, $r){
                    $acc[] = $r->id;
                    return $acc;
                }, []);
           });
      },
])

The reducer collects the book ids.
But I only get an empty result in books.

I belive its better to have the format results AFTER the contain. As the contain hasMany won’t have a way to match the two resultsets.

$author = $this->Authors->findById(id)->contain(['Books']);
$book_ids = collection($author->books)->extract('id')->toArray();
1 Like

Thanks, I didn’t use CakePhps collections at all until now.
Isn’t that the same as the plain old:
$book_ids = array_map(function ($book) { return $book->id; }, $author->books);
?

Back then, when I started with cake 2, I discovered Hash:combine and used it.
Until I noticed how absolutely inperformant it was compared to a simple for loop, that did the same.
So now I’m a bit skeptical about fancy code snippets that already exist in simple php.
Although I admit, with Collections the code is better to read.

Looks like that should do about the same, yes. I like collections, because they are very powerful and chainable, and I find it’s generally best for me to have my code consistent rather than fine-tune for performance in different situations.