Browse Source

Add ability to remove a defined join.

With BelongsToMany::find() appending joins, we'll need a way to redefine
and re-order those joins should the BelongsToMany association also be
eagerloaded/matched. Not being able to remove/re-order the joins results
in invalid SQL as the table ordering is wrong.

Refs #7707
Mark Story 10 years ago
parent
commit
f25eac3b46
2 changed files with 36 additions and 0 deletions
  1. 16 0
      src/Database/Query.php
  2. 20 0
      tests/TestCase/Database/QueryTest.php

+ 16 - 0
src/Database/Query.php

@@ -536,6 +536,22 @@ class Query implements ExpressionInterface, IteratorAggregate
     }
 
     /**
+     * Remove a join if it has been defined.
+     *
+     * Useful when you are redefining joins or want to re-order
+     * the join clauses.
+     *
+     * @param string $name The alias/name of the join to remove.
+     * @return $this
+     */
+    public function removeJoin($name)
+    {
+        unset($this->_parts['join'][$name]);
+        $this->_dirty();
+        return $this;
+    }
+
+    /**
      * Adds a single LEFT JOIN clause to the query.
      *
      * This is a shorthand method for building joins via `join()`.

+ 20 - 0
tests/TestCase/Database/QueryTest.php

@@ -3500,6 +3500,26 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Test removeJoin().
+     *
+     * @return void
+     */
+    public function testRemoveJoin()
+    {
+        $query = new Query($this->connection);
+        $query->select(['id', 'title'])
+            ->from('articles')
+            ->join(['authors' => [
+                'type' => 'INNER',
+                'conditions' => ['articles.author_id = authors.id']
+            ]]);
+        $this->assertArrayHasKey('authors', $query->join());
+
+        $this->assertSame($query, $query->removeJoin('authors'));
+        $this->assertArrayNotHasKey('authors', $query->join());
+    }
+
+    /**
      * Assertion for comparing a table's contents with what is in it.
      *
      * @param string $table