phpcakephpcontainable

CakePHP same result format as find('list') in Containable


I'm looking for a way to have the results of a query that uses the Containable behavior to be formatted the same way as find('list') results are. E.g.:

$this->ModelA->find('all', array(
    'contain' => array(
        'ModelB' => array(
            'ModelC' => array(
                // This does NOT work but I need ModelC's fields to be formatted as an associative array where IDs are keys and names are values
                'fields' => array('id' => 'name')
            )
        )
    )
));

NOTE: Setting recursive to 1 or 2 instead of using Containable is not an option unless there's no available solution with Containable.


Solution

  • I'm not sure you can get the returned contained data back in the format you want, but you can alter it after finding it. The way Cake actually builds the return from find('list') is using Hash::combine(). So you can alter the returned data using this to make the data look list a find('list') return:-

    $data = [
        [
            'id' => 1,
            'name' => 'Foo'
        ],
        [
            'id' => 2,
            'name' => 'Bar'
        ]
    ];
    $results = Hash::combine($data, '{n}.id', '{n}.name');
    

    This would return:-

    [
        1 => 'Foo',
        2 => 'Bar'
    ]
    

    Not sure exactly what your find('all') data looks like as you've not supplied the associations, but guess you can do something like this:-

    foreach ($data as &$row) {
        $row['ModelB']['ModelC'] = Hash::combine(
            $row['ModelB']['ModelC'], 
            '{n}.id', 
            '{n}.name'
        );
    }