I need id as key of result set from find()


#1

Hi!
First, find(‘list’) doesn’t do job for me, it doesn’t return entities.
Let’s say I’ve got table:

id vakue1 … others columns, that I need in my result
50 a
51 b
63 c

standard result is
key of array
0 => [id=>50,value=>a, others columns…]
1 => [id=>51,value=>b, others columns…]
2 => [id=>63,value=>c, others columns…]

what I want is:
50 => [id=>50,value=>a, others columns…]
51 => [id=>51,value=>b, others columns…]
63 => [id=>63,value=>c, others columns…]

For now, i rewrite whole result to new array creating desired keys, but maybe there is a better way? Creating them when shifting data from DB? I try with “custom finders” but I cant.
Can you help? (I’m using Cakephp 3.0)
Jarek


#2

I think the best option to use Hash after calling find()
https://book.cakephp.org/3.0/en/core-libraries/hash.html


#3

I made my AppTable and a listEntites custom finder based on the findList source code, I think it can be tweaked but for now works for me

function findListEntities(Query $query, array $options)
{
    $options += [
        'keyField' => $this->getPrimaryKey(),
        'groupField' => null
    ];
    $options = $this->_setFieldMatchers(
        $options,
        ['keyField', 'groupField']
    );

    return $query
        ->find('list', $options)
        ->select($this)
        ->formatResults(
            function ($results) use ($options) {
                return $results->combine(
                    $options['keyField'],
                    function ($entity) { return $entity; },
                    $options['groupField']
                );
            },
            true // overwrite formatResults
        );
}

#4

Using Hash after a find works well for me too. Here is an example for you.

use Cake\Utility\Hash;

$supplier_result = $this->loadModel(‘Users’)->find()
->select([‘Users.id’,‘Suppliers.provider_name’])
->contain([‘Suppliers’])
->toArray();

$supplier_list = Hash::combine($supplier_result, ‘{n}.id’,’{n}.supplier.provider_name’);

You could add more fields to the array as you wish and combine function will work magic for you.


#5

Thanks for replies. But if I use Hash::combine() after find()…->toArray() will it not be the same as using foreach? I mean take row X, change, save to another array?
@raul338 I see combine in your function also, but it so complex, that I’m not sure how it works :slight_smile:
I will give it a try, when I return to that part of my project.
Does your method return array of entities (objects)?


#6

Yes.
I took most the code of the original findList function.

And the combine function is from Collections class, look at the very last example.

Yes. It does return an array of Entities with the keyField (identical like the findList works), and optionally grouped by groupField (thats the combine call).
Like any other finder, you can mix/chain it with others options/finders