Browse Source

Fix duplicate column errors in IsUnique rules.

Refs #5877
Mark Story 11 years ago
parent
commit
14dfc65fc9
2 changed files with 45 additions and 2 deletions
  1. 19 2
      src/ORM/Rule/IsUnique.php
  2. 26 0
      tests/TestCase/ORM/RulesCheckerIntegrationTest.php

+ 19 - 2
src/ORM/Rule/IsUnique.php

@@ -53,10 +53,11 @@ class IsUnique
             return true;
         }
 
-        $conditions = $entity->extract($this->_fields);
+        $alias = $options['repository']->alias();
+        $conditions = $this->_alias($alias, $entity->extract($this->_fields));
         if ($entity->isNew() === false) {
             $keys = (array)$options['repository']->primaryKey();
-            $keys = $entity->extract($keys);
+            $keys = $this->_alias($alias, $entity->extract($keys));
             if (array_filter($keys, 'strlen')) {
                 $conditions['NOT'] = $keys;
             }
@@ -64,4 +65,20 @@ class IsUnique
 
         return !$options['repository']->exists($conditions);
     }
+
+    /**
+     * Add a model alias to all the keys in a set of conditions.
+     *
+     * @param string $alias The alias to add.
+     * @param array $conditions The conditions to alias.
+     * @return array
+     */
+    protected function _alias($alias, $conditions)
+    {
+        $aliased = [];
+        foreach ($conditions as $key => $value) {
+            $aliased["$alias.$key"] = $value;
+        }
+        return $aliased;
+    }
 }

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

@@ -550,6 +550,32 @@ class RulesCheckerIntegrationTest extends TestCase
     }
 
     /**
+     * Tests the existsIn with coflicting columns
+     *
+     * @group save
+     * @return void
+     */
+    public function testExistsInAliasPrefix()
+    {
+        $entity = new Entity([
+            'title' => 'An Article',
+            'author_id' => 1
+        ]);
+
+        $table = TableRegistry::get('Articles');
+        $table->belongsTo('Authors');
+        $rules = $table->rulesChecker();
+        $rules->add($rules->isUnique(['author_id']));
+
+        $table->Authors->eventManager()->on('Model.beforeFind', function ($event, $query) {
+            $query->leftJoin(['a2' => 'authors']);
+        });
+
+        $this->assertFalse($table->save($entity));
+        $this->assertEquals(['_isUnique' => 'This value is already in use'], $entity->errors('author_id'));
+    }
+
+    /**
      * Tests the existsIn rule when passing non dirty fields
      *
      * @group save