I have a registration form in which users can fill in two email address (email1 & email2). Marketing's requirement is that they need to be unique (unique as in if we had 10 users, then there would be 10*2=20 unique email address).
The system is already built on cakephp, so what I'd like to know is, is there something similar to the isUnique feature (unique in one field) that can do this right out of the box? Or am I doomed to code this myself? Thanks in advance.
EDIT: built on Richard's example, this worked for me:
function checkUnique($data, $fields) {
if (!is_array($fields)) {
$fields = array($fields);
}
foreach($data as $key) {
$checks = $key;
}
if (empty($checks)) {
return true; //allow null
}
foreach($fields as $key) {
$tmp[$key] = $checks;
}
if (isset($this->data[$this->name][$this->primaryKey])) {
$tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this->primaryKey];
}
return $this->isUnique($tmp);
}
As far as I remember, you have to this kind of enforcement using the
beforeSave
method in the model. I had a requirement that an object have at least one of N fks set, and I could only do it this way.Edit: try this thread to see if anything there solves your problem.
Yes and no.
Yes, you will have to code it yourself, but within the CakePHP validation component.
The validation component has a mechanism to allow custom validation rules. Essentially, you put a function name inside $validate (like you normally would). You do have to define the function; in this case, it's pretty simple (just enforce your double isUnique requirement).
http://book.cakephp.org/2.0/en/models/data-validation.html#custom-validation-rules
I posted a solution to this on the CakePHP Google Group:
http://groups.google.com/group/cake-php/browse_frm/thread/b3a1e4ae3eeb6091/e168f54bac27c163?lnk=gst&q=checkUnique#e168f54bac27c163
Add the following to your AppModel:
and is used in your model validate:
From cakePHP 2.0 documentation:
You can validate that a set of fields are unique by providing multiple fields and set $or to false:
Make sure to include the original field in the list of fields when making a unique rule across multiple fields.
If a listed field isn’t included in the model data, then it’s treated as a null value. You may consider marking the listed fields as required.
At the risk of being beaten about the head and shoulders for offering a non-CakePHP solution, let me present the following.
Create a unique index in your database over however many columns you need.
Standard SQL syntax for this is:
Place your "$this->Model->save()" command inside of a "try/catch" block. In the "catch" block, test the exception for the error code. In MySQL, a unique key violation is error code 23000, but you should be prepared for other possible errors as well.
It's quick and simple and doesn't involve counting array parentheses.
You should always place database access code inside a "try/catch" block anyway. Part of your exception handling should include logging any unexpected error messages. You can't expect CakePHP to do everything for you.
checkUnique
could just be written as a wrapper forisUnique
.and is used in your model validate: