Browse Source

Fix IsUnique rule & null values

IsUnique rules across multiple fields with nulls should be detected
correctly. With this change `IS NULL` is emitted instead of `= NULL`.

Refs #8803
Mark Story 10 years ago
parent
commit
02c8f32054
2 changed files with 28 additions and 1 deletions
  1. 1 1
      src/ORM/Rule/IsUnique.php
  2. 27 0
      tests/TestCase/ORM/RulesCheckerIntegrationTest.php

+ 1 - 1
src/ORM/Rule/IsUnique.php

@@ -77,7 +77,7 @@ class IsUnique
     {
         $aliased = [];
         foreach ($conditions as $key => $value) {
-            $aliased["$alias.$key"] = $value;
+            $aliased["$alias.$key IS"] = $value;
         }
         return $aliased;
     }

+ 27 - 0
tests/TestCase/ORM/RulesCheckerIntegrationTest.php

@@ -370,6 +370,33 @@ class RulesCheckerIntegrationTest extends TestCase
     }
 
     /**
+     * Tests isUnique with multiple fields and a nulled field.
+     *
+     * @group save
+     * @return void
+     */
+    public function testIsUniqueMultipleFieldsOneIsNull()
+    {
+        $entity = new Entity([
+            'author_id' => null,
+            'title' => 'First Article'
+        ]);
+        $table = TableRegistry::get('Articles');
+        $rules = $table->rulesChecker();
+        $rules->add($rules->isUnique(['title', 'author_id'], 'Nope'));
+
+        $this->assertSame($entity, $table->save($entity));
+
+        // Make a duplicate
+        $entity = new Entity([
+            'author_id' => null,
+            'title' => 'First Article'
+        ]);
+        $this->assertFalse($table->save($entity));
+        $this->assertEquals(['title' => ['_isUnique' => 'Nope']], $entity->errors());
+    }
+
+    /**
      * Tests the existsIn domain rule
      *
      * @group save