Orbitum
Orbitum

Reputation: 1645

CakePHP: SaveAll() and hasMany data replace problem

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.

Upvotes: 1

Views: 4981

Answers (3)

Orbitum
Orbitum

Reputation: 1645

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);

Upvotes: 3

Anh Pham
Anh Pham

Reputation: 5481

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.

Upvotes: 3

Ronny Vindenes
Ronny Vindenes

Reputation: 2361

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 *** );

Upvotes: 0

Related Questions