Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP return find('all') using 'id' as array Index

So I'm trying to return a find 'all' array using the id of a 'Product' as the index key for each Product.

Typically it returns:

array(
    (int) 0 => array(
        'Product' => array(
            'id' => '1232',
            'category_id' => '330',
            'name' => 'Product #1',
        )
    ),
    (int) 1 => array(
        'Product' => array(
            'id' => '1245',
            'category_id' => '310',
            'name' => 'Product #2',
        )
    ),
    (int) 2 => array(
        'Product' => array(
            'id' => '1248',
            'category_id' => '312',
            'name' => 'Product #3',
        )
    )
)

Whereas ideally I'd like it to return:

array(
    (int) 1232 => array(
        'Product' => array(
            'id' => '1232',
            'category_id' => '330',
            'name' => 'Product #1',
        )
    ),
    (int) 1245 => array(
        'Product' => array(
            'id' => '1245',
            'category_id' => '310',
            'name' => 'Product #2',
        )
    ),
    (int) 1248 => array(
        'Product' => array(
            'id' => '1248',
            'category_id' => '312',
            'name' => 'Product #3',
        )
    )
)

Is this possible? And how do I go about doing it?

I have an excel spreadsheet of records that I need to match ID's to, so currently I have it iterating each spreadsheet row and performing a 'first' find to get any results, then act upon them if they do.

It works, but the recordset has grown to over 28000 and so performing one find for each has noticeable overhead.

If I can do this simply in the 'find' operation it would be great, if not, any noticeable increase in performance would be appreciated.

like image 580
sneexz Avatar asked Dec 15 '22 18:12

sneexz


2 Answers

You can get this result as after find all :

$result = Hash::combine($data, '{n}.Product.id', '{n}.Product');

Where $data is the result of find all.

like image 162
Prakash Saini Avatar answered Dec 17 '22 08:12

Prakash Saini


You can have your find method extended in AppModel like this

public function find($type = 'first', $query = array()) {
    switch($type) {
        case 'keysid':

            if($results = parent::find('all', $query)){

                if(isset($results[0][$this->alias]['id'])){

                    return Hash::combine($results, '{n}.'.$this->alias.'.id', '{n}');
                }else{
                    return $results;
                }

            } 
        break;
        default:
            return parent::find($type, $query);
            break;
    }
}

And afterwards you can call your find method as follows:

$this->Product->find('keysid');

Then you will have a result array as you specified. However you can also do this with one line of code if you need it once. Say $products is your array from the find('all')

if($products = $this->Product->find('all')){
        $alteredProducts = Hash::combine($products, '{n}.Product.id', '{n}');
    }

Have a look at the Hash utility

like image 43
elha Avatar answered Dec 17 '22 06:12

elha