Permalink
Browse files

Fix Model::isUnique() not working as a validator.

While it *did* work for single fields, isUnique could not be used to
validate the uniqueness across multiple fields as documented. Because
validation methods pass arguments in an order the validator did not
expect the validation method would not work correctly.

Fixes #4571
  • Loading branch information...
markstory committed Oct 10, 2014
1 parent 0ff9545 commit 39011cd9d8def8308629991af5f5bda0d01040d1
Showing with 53 additions and 1 deletion.
  1. +9 −1 lib/Cake/Model/Model.php
  2. +44 −0 lib/Cake/Test/Case/Model/ModelValidationTest.php
View
@@ -3293,11 +3293,19 @@ public function resetAssociations() {
/**
* Returns false if any fields passed match any (by default, all if $or = false) of their matching values.
*
+ * Can be used as a validation method. When used as a validation method, the `$or` parameter
+ * contains an array of fields to be validated.
+ *
* @param array $fields Field/value pairs to search (if no values specified, they are pulled from $this->data)
- * @param bool $or If false, all fields specified must match in order for a false return value
+ * @param bool|array $or If false, all fields specified must match in order for a false return value
* @return bool False if any records matching any fields are found
*/
public function isUnique($fields, $or = true) {
+ if (is_array($or)) {
+ $args = func_get_args();
+ $fields = $args[1];
+ $or = isset($args[2]) ? $args[2] : true;
+ }
if (!is_array($fields)) {
$fields = func_get_args();
if (is_bool($fields[count($fields) - 1])) {
@@ -2405,6 +2405,50 @@ public function testValidateManyAtomicFalseDeepTrueWithErrors() {
$this->assertEquals($expected, $result);
}
+/**
+ * Test the isUnique method when used as a validator for multiple fields.
+ *
+ * @return void
+ */
+ public function testIsUniqueValidator() {
+ $this->loadFixtures('Article');
+ $Article = ClassRegistry::init('Article');
+ $Article->validate = array(
+ 'user_id' => array(
+ 'duplicate' => array(
+ 'rule' => array('isUnique', array('user_id', 'title'), false)
+ )
+ )
+ );
+ $data = array(
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ );
+ $Article->create($data);
+ $this->assertFalse($Article->validates(), 'Contains a dupe');
+
+ $data = array(
+ 'user_id' => 1,
+ 'title' => 'Unique Article',
+ );
+ $Article->create($data);
+ $this->assertTrue($Article->validates(), 'Should pass');
+
+ $Article->validate = array(
+ 'user_id' => array(
+ 'duplicate' => array(
+ 'rule' => array('isUnique', array('user_id', 'title'))
+ )
+ )
+ );
+ $data = array(
+ 'user_id' => 1,
+ 'title' => 'Unique Article',
+ );
+ $Article->create($data);
+ $this->assertFalse($Article->validates(), 'Should fail, conditions are combined with or');
+ }
+
}
/**

0 comments on commit 39011cd

Please sign in to comment.