I came across this post that gave an answer on how to do this but it's not quite working for me.
I have a model called SitePage
which has many SitePageGroup
which in turn has many SitePageContent
// SitePage Model
public $hasMany = array(
'SitePageGroup' => array(
'className' => 'FoCMS.SitePageGroup',
'foreignKey' => 'site_page_id',
'dependent' => FALSE,
),
);
// SitePageGroup Model
public $belongsTo = array(
'SitePage' => array(
'className' => 'FoCMS.SitePage',
'foreignKey' => 'site_page_id',
),
);
public $hasMany = array(
'SitePageContent' => array(
'className' => 'FoCMS.SitePageContent',
'foreignKey' => 'site_page_group_id',
'dependent' => FALSE,
),
);
// SitePageContent Model
public $belongsTo = array(
'SitePageGroup' => array(
'className' => 'FoCMS.SitePageGroup',
'foreignKey' => 'site_page_group_id',
),
);
Using the answer in that linked question I am seeing the parent model, SitePage
being duplicated, but the associated models are being removed from the original and associated with the new one.
$record = $this->SitePage->find('first', array('condition' => array('SitePage.id' => $id)));
unset($record['SitePage']['id'], $record['SitePageGroup']['id'], $record['SitePageGroup']['SitePageContent']['id'] /* further ids */);
$this->SitePage->create();
$record['SitePage']['name'] = $record['SitePage']['name'].'-copy';
$record['SitePage']['friendly_name'] = $record['SitePage']['friendly_name'].' Copy';
if($this->SitePage->saveAll($record)){
$this->Session->setFlash('The site page has been saved', 'fo_message');
$this->redirect(array('action' => 'index'));
}else{
$this->Session->setFlash('The site page could not be saved. Please, try again.', 'fo_message');
}
Update
Debugging the record that I'm trying to reset I see the following
array(
'SitePage' => array(
'name' => 'test',
'friendly_name' => 'Test',
'order' => '82',
'created' => '2015-09-03 19:16:40',
'modified' => '2015-09-03 19:20:27'
),
'SitePageGroup' => array(
(int) 0 => array(
'id' => '55e88087-a4dc-4c37-89dc-f9c172b40463',
'site_page_id' => '55e88078-16c8-46ce-bf02-fa5372b40463',
'name' => 'group-1',
'friendly_name' => 'Group 1',
'order' => '1',
'created' => '2015-09-03 19:16:55',
'modified' => '2015-09-03 19:16:55'
),
(int) 1 => array(
'id' => '55e8809e-d018-4ebe-a4cf-fbef72b40463',
'site_page_id' => '55e88078-16c8-46ce-bf02-fa5372b40463',
'name' => 'group-2',
'friendly_name' => 'Group 2',
'order' => '2',
'created' => '2015-09-03 19:17:18',
'modified' => '2015-09-03 19:17:18'
)
)
)
The way I am getting this result is by doing this
$sitePage = $this->SitePage->find('first', array(
'conditions' => array(
'SitePage.id' => $id,
),
));
unset($sitePage['SitePage']['id'], $sitePage['SitePageGroup']['id'], $sitePage['SitePageGroup']['SitePageContent']['id'], $sitePage['SitePageGroup']['site_page_id'], $sitePage['SitePageGroup']['SitePageContent']['site_page_group_id'] /* further ids */);
debug($sitePage);
die();
But also also as you can see in the debug output the 3rd level of associated models are not being included, each of the SitePageGroup
should also have a SitePageContent
I think a simple loop over the array of SitePageGroup
should reset the id's and set the foreign keys to null, but I guess I also need to somehow include the SitePageContent
that belongs to the SitePageGroup
so I can reset those as well.
You need to ensure that all primary and foreign keys are set to null
before saving. You only appear to be resetting the primary keys of your models but Cake needs to know that the foreign keys need generating so that they reference the new records.
Before calling $record
it might be worth using debug($record);
to check that everything in that array has been set/reset appropriately to ensure the copy will work as expected.
Update
Based on the array contents you've posted in your updated question it appears that you are not removing all the primary and foreign keys from your save data. You need to make sure that these are removed from everything you are about to save including the has many associations.
If you look at your array you should be able to see that unset($sitePage['SitePageGroup']['id'])
will not remove the primary IDs of your SitePageGroup
data as what you are unsetting doesn't correspond to array paths in your $sitePage
array.
You can use CakePHP's Hash utility to remove the primary keys from the array like this:-
$sitePage = Hash::remove($sitePage, 'SitePageGroup.{n}.id');
And similarly for the foreign keys:-
$sitePage = Hash::remove($sitePage, 'SitePageGroup.{n}.site_page_id');