Cakephp unique validation in 1.2
September 21st, 2007 | by useful | in Programming |A little disclaimer: I could be totally wrong because I’m still learning the ins and outs of CakePHP.
I don’t like the current solution for validation of unique fields in the 1.2 CakePHP AppModel mainly because I couldn’t get it to work so I created my own. Sorry about the formatting, I’ve never posted code in my blog before and not being able to properly indent the code isn’t a big concern for me. The code was inspired by the comments between speedmax and cakebaker on his blog.
// YourModel.php
var $validate = array( // validate our username and email
'username' => array('rule' => array('alphaNumeric')),
'email' => array('rule' => array('email'))
);
function beforeSave() {
$check = array('username','email'); // username and email are unique
return $this->checkUnique($check);
}
The code above specifies username and email as unique values and will check for them in the database before we save. Below is my modified app model.
// AppModel.php
class AppModel extends Model {
function checkUnique($myUnique) {
$sql = "";
foreach($myUnique as $name ) {
if($sql!="") $sql.=' OR ';
$sql .= $this->name.".$name=\"".$this->data[$this->name][$name].’”‘;
}
$found = $this->find($sql);
$same = isset($this->id) && $found[$this->name]['id'] == $this->id;
return !$found || $found && $same;
}
}
Now in the controller all you have to do is save your data.
if($this->YourModel->save($this->data)) {
// success
} else {
// failure
}
The code runs save() -> validate() -> beforeSave() -> checkUnique() and wont save to mysql if validate or beforeSave is false. I think the code is a little more strait-forward compared to making countless arrays within arrays.

December 7th, 2007 at 8:27 am
hello, at the moment i have the same problem, but i think the model implements a method isUnique and this do the same
$this->model->isUnique(’value’);
December 7th, 2007 at 9:27 am
my validation looks like:
var $validate = array(’email’ => array(’not_unique’ => array(’rule’ => array(’validateUnique’, ‘field’ => ‘email’)),’not_valid’ => VALID_EMAIL, ‘not_empty’ => VALID_NOT_EMPTY));
function validateUnique($value, $field)
{
$valid = false;
$valid = $this->isUnique(array($field => $value));
return $valid;
}
December 7th, 2007 at 1:56 pm
The reason I made my own unique check is that my version of 1.2 has a bug in isUnique and always returns 0 because it sets the field equal to the value.
Your way of validation seems to take a database call for each unique. If isUnique now works in 1.2 my ideal way to use it is:
var $validate = array( // validate our username and email
‘username’ => array(’rule’ => array(’alphaNumeric’)),
‘email’ => array(’rule’ => array(’email’))
);
function beforeSave() {
$check = array(’username’,'email’); // username and email are unique
return $this->isUnique($check); // isUnique returns #fields matching
}