From 795a09c27afc779bd8315654a8614b1433994178 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 5 Jan 2014 17:42:40 -0500 Subject: [PATCH] Fixes #1791: joinWithRelation using table alias. --- framework/yii/db/ActiveQuery.php | 30 ++++++++++++++++++---------- tests/unit/framework/db/ActiveRecordTest.php | 14 +++++++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/framework/yii/db/ActiveQuery.php b/framework/yii/db/ActiveQuery.php index dc00661..556f15f 100644 --- a/framework/yii/db/ActiveQuery.php +++ b/framework/yii/db/ActiveQuery.php @@ -326,11 +326,11 @@ class ActiveQuery extends Query implements ActiveQueryInterface } /** - * Returns the table alias (or table name) that can be used to prefix column names. + * Returns the table name and the table alias for [[modelClass]]. * @param ActiveQuery $query - * @return string the table alias (or table name) enclosed within double curly brackets. + * @return array the table name and the table alias. */ - private function getQueryTableAlias($query) + private function getQueryTableName($query) { if (empty($query->from)) { /** @var ActiveRecord $modelClass */ @@ -341,12 +341,12 @@ class ActiveQuery extends Query implements ActiveQueryInterface } if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) { - $tableName = $matches[2]; - } - if (strpos($tableName, '{{') === false) { - $tableName = '{{' . $tableName . '}}'; + $alias = $matches[2]; + } else { + $alias = $tableName; } - return $tableName; + + return [$tableName, $alias]; } /** @@ -372,13 +372,21 @@ class ActiveQuery extends Query implements ActiveQueryInterface return; } - $parentTable = $this->getQueryTableAlias($parent); - $childTable = $this->getQueryTableAlias($child); + list ($parentTable, $parentAlias) = $this->getQueryTableName($parent); + list ($childTable, $childAlias) = $this->getQueryTableName($child); if (!empty($child->link)) { + + if (strpos($parentAlias, '{{') === false) { + $parentAlias = '{{' . $parentAlias . '}}'; + } + if (strpos($childAlias, '{{') === false) { + $childAlias = '{{' . $childAlias . '}}'; + } + $on = []; foreach ($child->link as $childColumn => $parentColumn) { - $on[] = "$parentTable.[[$parentColumn]] = $childTable.[[$childColumn]]"; + $on[] = "$parentAlias.[[$parentColumn]] = $childAlias.[[$childColumn]]"; } $on = implode(' AND ', $on); } else { diff --git a/tests/unit/framework/db/ActiveRecordTest.php b/tests/unit/framework/db/ActiveRecordTest.php index 40050e5..0366fa9 100644 --- a/tests/unit/framework/db/ActiveRecordTest.php +++ b/tests/unit/framework/db/ActiveRecordTest.php @@ -276,5 +276,19 @@ class ActiveRecordTest extends DatabaseTestCase $this->assertEquals(3, count($orders[0]->items)); $this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); $this->assertEquals(2, $orders[0]->items[0]->category->id); + + // join with table alias + $orders = Order::find()->joinWith([ + 'customer' => function ($q) { + $q->from('tbl_customer c'); + } + ])->orderBy('c.id DESC, tbl_order.id')->all(); + $this->assertEquals(3, count($orders)); + $this->assertEquals(2, $orders[0]->id); + $this->assertEquals(3, $orders[1]->id); + $this->assertEquals(1, $orders[2]->id); + $this->assertTrue($orders[0]->isRelationPopulated('customer')); + $this->assertTrue($orders[1]->isRelationPopulated('customer')); + $this->assertTrue($orders[2]->isRelationPopulated('customer')); } }