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,
`notes` text collate latin1_general_ci,
`modified` datetime default NULL,
`created` datetime default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clientpost` (`client_id`,`post_id`)
);
`id` int(11) NOT NULL auto_increment,
`client_id` int(11) NOT NULL,
`post_id` int(11) NOT NULL,
`notes` text collate latin1_general_ci,
`modified` datetime default NULL,
`created` datetime default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `clientpost` (`client_id`,`post_id`)
);
The Models
models/post.php
models/client_to_post.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;
if(isset($this->data[$this->alias]['created'])) unset($this->data[$this->alias]['created']);
}
}
}
}
}
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;
if(isset($this->data[$this->alias]['created'])) unset($this->data[$this->alias]['created']);
}
}
}
}
}
The Controller
controllers/posts_controller.phpclass 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);
}
}
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);
}
}
