cant saveall on 1 model with cakephp

352 views Asked by At

I cant saveall records to the 1 model. I have a numerical array which i added a model name.

For saving multiple records of single model, $data needs to be a numerically indexed array of records :' I did this and also tried many varieties with Tutor as the key. I don't get anything saves as i get the error message below instead. I don't know what i am doing wrong but it cant be much with such a common function. I looked at other posts and I can't see my error.

http://book.cakephp.org/2.0/en/models/saving-your-data.html

if ($this->request->is('post') || $this->request->is('put')) {
    $tutordata=$this->request->data['Tutor'];
    //debug( $tutordata);
    $data=array();
    $this->Tutor->create();

    foreach ($tutordata as  $key => $item): 
        $data['Tutor'][$key]['id']=$item['id'];
        $data['Tutor'][$key]['payrate_10']=$item['payrate_10'];
        $data['Tutor'][$key]['payrate_vce']=$item['payrate_vce'];
        $data['Tutor'][$key]['payrate_assessment']=$item['payrate_assessment'];
    endforeach;

    debug( $data);
    //  $data=$this->request->data['Tutor'];
    //   if ($this->Tutor->saveAll($data)){ 
    if ($this->Tutor->saveAll($data['Tutor'])){
        //  return $this->redirect(array('action' => 'edit_paycycle'));
        $this->Session->setFlash(__('Your Pay Rates have been saved .'));
    }
    else{
        $this->Session->setFlash(__('2ERROR! Your Pay Rates have not been saved .'));
    }
}

This is the data array

array(
    'Tutor' => array(
        (int) 0 => array(
            'id' => '13',
            'payrate_10' => '25.00',
            'payrate_vce' => '25.00',
            'payrate_assessment' => '50.00'
        ),
        (int) 1 => array(
            'id' => '7',
            'payrate_10' => '30.00',
            'payrate_vce' => '45.00',
            'payrate_assessment' => '0.00'
        ),
        ....
    )
);
2

There are 2 answers

1
Lukasstr On BEST ANSWER

Sry to say this but your use of saveall is awkward. With save you usually want to create new records and don't specify an id field. So perhaps you get ploblems cause cakephp expects an update and one of the id's is already existent in the database.

Btw. you can simplify your foreach with:

foreach ($tutordata as  $item){
    $data['Tutor'][] = [
        'id'=>$item['id'],
        'payrate_10'=>$item['payrate_10'],
        'payrate_vce'=>$item['payrate_vce'],
        'payrate_assessment'=>$item['payrate_assessment']
    ];
};

Instead of using saveAll you could use saveMany as you only save data for one model. If you pass an numeric array to saveAll(like u do) it will automatically map to saveMany, but you would save the mapping.

edit: so now I got your problem :) cake has no way to know if phone was already set, so a validation on the current entry will return a error.

So what you can do to resolve this is:

turning general validation off: http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array and do specific validation on the fields you want to.

Or make hidden fields in your view which keep the actual values.

Or last and worst solution: make a $model->find('all') with the id's in condition and merge it with the input from your view.

edit: and the most likely best thing would be if you simply replace the required by notEmpty in your model http://book.cakephp.org/2.0/en/models/data-validation.html#required

2
drmonkeyninja On

If you're trying to update existing rows then you shouldn't be using $this->Tutor->create(); as this instructs Cake to create a new record. This is probably the cause of your problems.

There seems to be little point to your foreach loop other than to perhaps whitelist which fields you want to save which can be done using the fieldList option:-

if ($this->request->is('post') || $this->request->is('put')) {
    $result = $this->Tutor->saveMany(
        $this->request->data['Tutor'],
        'fieldList' => array(
            'Tutor' => array(
                'id',
                'payrate_10',
                'payrate_vce',
                'payrate_assessment'
            )
        )
    );

    if ($result !== false) {
        $this->Session->setFlash(__('Your Pay Rates have been saved .'));
    } else {
        $this->Session->setFlash(__('2ERROR! Your Pay Rates have not been saved .'));
    }
}

As others have stated there's no need to use saveAll() as you're saving many rows of the same model so saveMany() is more appropriate. saveAll() should be avoided as it implies that you're not sure what you are actually trying to save; it is mainly there for backwards compatiblity:-

This function receives the same options as the former two, and is generally a backwards compatible function. It is recommended using either saveMany or saveAssociated depending on the case.