CakePHP 4 Duplicate Save to Associated Table

Saving and duplicating data into the associated table? This quick tutorial will show how to save data and duplicate it into the associated table. For this tutorial, I set 2 tables, i) users and ii) clones where the input process will be executed in the table users and duplicate into table clones.


The Tables
Table: users

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| fullname | varchar(255) | NO   |     | NULL    |                |
| email    | varchar(255) | NO   |     | NULL    |                |
| gender   | int(1)       | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+


Table: clones

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id  | int(11)      | NO   |     | NULL    |                |
| fullname | varchar(255) | NO   |     | NULL    |                |
| email    | varchar(255) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+


Save and Duplicate
In this tutorial, the table users is associated with table clones. The idea is to save the input data from table users into table clones together with the user_id. To ensure that we capture the user_id into the table clones, we need to execute the associated save after users save method.

use Cake\ORM\TableRegistry; //add this at the beginning of the controller

public function add()
{
	$user = $this->Users->newEmptyEntity();
	if ($this->request->is('post')) {
		$user = $this->Users->patchEntity($user, $this->request->getData());
		if ($this->Users->save($user)) {
			//save clone
			$clonesTable = TableRegistry::getTableLocator()->get('Clones');
			$cloneData = [
				'fullname' => $this->request->getData('fullname'),
				'email' => $this->request->getData('email'),
				'user_id' => $user->id,
			];
			$clone = $clonesTable->newEntity($cloneData);
			$clonesTable->save($clone);

			$this->Flash->success(__('The user and clone has been saved.'));
			return $this->redirect(['action' => 'index']);
		}
		$this->Flash->error(__('The user could not be saved. Please, try again.'));
	}
	$this->set(compact('user'));
}


If we assume that the clones table is not related to table users, then you can duplicate the data using the following codes (before user save or also can use above method):

use Cake\ORM\TableRegistry; //add this at the beginning of the controller

public function add()
{
	$user = $this->Users->newEmptyEntity();
	if ($this->request->is('post')) {
		$user = $this->Users->patchEntity($user, $this->request->getData());
			$clonesTable = TableRegistry::getTableLocator()->get('Clones');
			$cloneData = [
				'fullname' => $this->request->getData('fullname'),
				'email' => $this->request->getData('email'),
			];
			$clone = $clonesTable->newEntity($cloneData);
		
		if ($this->Users->save($user) && $clonesTable->save($clone)) {
			$this->Flash->success(__('The user has been saved.'));
			return $this->redirect(['action' => 'index']);
		}
		$this->Flash->error(__('The user could not be saved. Please, try again.'));
	}
	$this->set(compact('user'));
}


That's all. Happy coding :)