1
votes

I made one big form with many associations hasMany/HABTM. All is workin great on creating (!). When updating all is working nice too, but in tables where association is hasMany, data is not updated or replaced, but just inserted. This brings many rows with trash data. How can I make saveAll() do the update/replace in hasMany fields:

Model:

class MainModel extends AppModel {

  var $hasAndBelongsToMany = array(
    'HABTMModel1',
    ...
    'HABTMModeln',
  );

  var $hasMany = array(
    'Model1' => array(
      'dependent' => true
     ),
     ...
    'Modeln' => array(
      'dependent' => true
    ),
  );
}

One of the problematic hasMany models look like:

class Model1 extends AppModel {

  var $belongsTo = array(
    'MainModel'
  );
}

And his table have:

id <- Primary key, auto increment, int (11)
main_model_id <- Foreign_key int (11)
name <- text field, string

The $this->data is looking like:

array(
  [MainModel] => array(
    'id' => 123
    *** aditional data named identicaly to table fields (working great)***
  ),
  [Model1] => array(
    [0] => array(
      [name] => Test1
    ),
    [2] => array(
      [name] => Test2
    ),
  ),
  *** all other models ***
);

Model1 table results after first creating and after updating:

id        main_model_id        name
--------------------------------------------------------------
11        306                 Test1
12        306                 Test2
13        306                 Test1  (Thease are dublicates)
14        306                 Test2  (Thease are dublicates)

What can I do to update/replace data in hasMany and not insert new values un edit using saveAll ?

Thank you.

3

3 Answers

3
votes

In the view, just put hidden input for all the Model1, Model2 ids

echo $form->create('MainModel');
echo $form->hidden('Model1.0.id');
// more stuffs...
echo $form->end('Save');

You probably specify the 'fields' for Model1, Model2 to have only 'name'. That's why $this->data looks like that. So just add 'id' to that.

3
votes

So I made not so beautiful, but working:

// If edit, then delete data from hasMany tables based on main_model_id
if(isset($this->data['MainModel']['id']) && !empty($this->data['MainModel']['id'])) {
  $conditions = array('main_model_id' => $this->data['MainModel']['id']);

  // Delete Model1
  $this->MainModel->Model1->deleteAll($conditions, false);

  ...
  all other models
  ...
}

$this->MainModel->saveAll($this->data);
0
votes

You need to set the id field for your hasMany model too e.g.

array(  
 [MainModel] => array(
    [id] => 123
    *** aditional data named identicaly to table fields (working great)***   ), 
  [Model1] => array(
    [0] => array(
      [id] => 1,
      [name] => Test1
    ),
    [2] => array(
      [id] => 2
      [name] => Test2
    ),   ),   *** all other models *** );