Auto-Set the ID beforeSave in CakePHP

In this quick snippet of code I will be setting the ID of a model based on other fields given. We want to save a note about each Post that is different for every Client, however we do not want to have to get the ID every time we save the data.

The Tables

CREATE TABLE IF NOT EXISTS `clients_to_posts` (
  `id` int(11) NOT NULL auto_increment,
  `client_id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `clientpost` (`client_id`,`post_id`)
);

The Models

models/post.php
<?php
class Post extends AppModel {
	var $name = 'Post';

	var $hasMany = array(
		'PostToClient' => array(
			'className' => 'PostToClient',
			'foreignKey' => 'post_id',
		),
	);
}
?>
models/client_to_post.php
<?php
class ClientToPost extends AppModel {
	var $name = 'ClientToPost';
	var $useTable = 'clients_to_posts';
	var $primaryKey = 'id';

	var $belongsTo = array(
		'Post' => array(
			'className' => 'Post',
			'foreignKey' => 'post_id',
		),
		'Client' => array(
			'className' => 'Client',
			'foreignKey' => 'client_id',
		),
	);

	function beforeValidate() {
		$this->setExistingId();
		return true;
	}
	
	function beforeSave() {
		$this->setExistingId();
		return true;
	}
		
	
	/**
	 * tries to set an existing id (used in beforeSave/beforeValidate)
	 *
	 */
	function setExistingId() {
		if (!$this->id) {
			$d = $this->data[$this->alias];
			if ((isset($d['post_id']) && $d['post_id']) && (isset($d['client_id']) && $d['client_id'])) {
				$conditions = array();
				$conditions[$this->alias.'.post_id'] = $d['post_id']; 
				$conditions[$this->alias.'.client_id'] = $d['client_id']; 
				$this->recursive = -1;
				$id = $this->field($this->primaryKey,$conditions);
				if ($id) {
					$this->exists(true);
					$this->id = $this->data[$this->alias][$this->primaryKey] = $id;
				}
			}
		}
	}
	
}
?>

The Controller

controllers/posts_controller.php
<?php
class PostsController extends AppController
	var $name = 'Posts';

	function test() {
		// do not render a view, for testing
		$this->autoRender = false;

		// set the data to save
		$data = array(
			'ClientToPost' => array(
				// if you do not set an id, it will be auto-set if a matching row exists
				// 'id' => 1,
				'post_id' => 123,
				'client_id' => 456,
				'notes' => 'this is a note',
			),
		);

		// save the data, no row exists so a new row will be created
		$this->Post->ClientToPost->save($data);

		// save the data again, as a row exists with the given post/client it will be updated
		$this->Post->ClientToPost->save($data);
	}	
}
?>

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <b> <i> <strong> <cite> <em> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <css>, <diff>, <drupal5>, <html>, <javascript>, <php>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.