Browse Source

Fixes #1791: joinWithRelation using table alias.

tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
795a09c27a
  1. 30
      framework/yii/db/ActiveQuery.php
  2. 14
      tests/unit/framework/db/ActiveRecordTest.php

30
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 * @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)) { if (empty($query->from)) {
/** @var ActiveRecord $modelClass */ /** @var ActiveRecord $modelClass */
@ -341,12 +341,12 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} }
if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) { if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) {
$tableName = $matches[2]; $alias = $matches[2];
} } else {
if (strpos($tableName, '{{') === false) { $alias = $tableName;
$tableName = '{{' . $tableName . '}}';
} }
return $tableName;
return [$tableName, $alias];
} }
/** /**
@ -372,13 +372,21 @@ class ActiveQuery extends Query implements ActiveQueryInterface
return; return;
} }
$parentTable = $this->getQueryTableAlias($parent); list ($parentTable, $parentAlias) = $this->getQueryTableName($parent);
$childTable = $this->getQueryTableAlias($child); list ($childTable, $childAlias) = $this->getQueryTableName($child);
if (!empty($child->link)) { if (!empty($child->link)) {
if (strpos($parentAlias, '{{') === false) {
$parentAlias = '{{' . $parentAlias . '}}';
}
if (strpos($childAlias, '{{') === false) {
$childAlias = '{{' . $childAlias . '}}';
}
$on = []; $on = [];
foreach ($child->link as $childColumn => $parentColumn) { foreach ($child->link as $childColumn => $parentColumn) {
$on[] = "$parentTable.[[$parentColumn]] = $childTable.[[$childColumn]]"; $on[] = "$parentAlias.[[$parentColumn]] = $childAlias.[[$childColumn]]";
} }
$on = implode(' AND ', $on); $on = implode(' AND ', $on);
} else { } else {

14
tests/unit/framework/db/ActiveRecordTest.php

@ -276,5 +276,19 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(3, count($orders[0]->items)); $this->assertEquals(3, count($orders[0]->items));
$this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); $this->assertTrue($orders[0]->items[0]->isRelationPopulated('category'));
$this->assertEquals(2, $orders[0]->items[0]->category->id); $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'));
} }
} }

Loading…
Cancel
Save