Insert manual joins *after* generated joins.

Re-order query joins to make manually added joins be performed after
generated joins. This removes the need to workaround the current join
order, or redefine all association joins when you want to add an
additional join on a leaf table.

Refs #2179
Refs #2346
This commit is contained in:
mark_story 2014-03-23 21:09:08 -04:00
parent a89b313ce8
commit 2fe8c4050b
2 changed files with 47 additions and 0 deletions

View file

@ -1067,6 +1067,9 @@ class DboSource extends DataSource {
}
}
$originalJoins = $queryData['joins'];
$queryData['joins'] = array();
// Generate hasOne and belongsTo associations inside $queryData
$linkedModels = array();
foreach ($associations as $type) {
@ -1093,6 +1096,10 @@ class DboSource extends DataSource {
}
}
if (!empty($originalJoins)) {
$queryData['joins'] = array_merge($queryData['joins'], $originalJoins);
}
// Build SQL statement with the primary model, plus hasOne and belongsTo associations
$query = $this->buildAssociationQuery($Model, $queryData);

View file

@ -1268,6 +1268,46 @@ class MysqlTest extends CakeTestCase {
return (array)$data + $base;
}
/**
* test that read() places provided joins after the generated ones.
*
* @return void
*/
public function testReadCustomJoinsAfterGeneratedJoins() {
$db = $this->Dbo->config['database'];
$test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
$test->config['database'] = $db;
$this->Model = $this->getMock('TestModel9', array('getDataSource'));
$this->Model->expects($this->any())
->method('getDataSource')
->will($this->returnValue($test));
$this->Model->TestModel8 = $this->getMock('TestModel8', array('getDataSource'));
$this->Model->TestModel8->expects($this->any())
->method('getDataSource')
->will($this->returnValue($test));
$search = "LEFT JOIN `cake_test_db`.`test_model8` AS `TestModel8` ON " .
"(`TestModel8`.`name` != 'larry' AND `TestModel9`.`test_model8_id` = `TestModel8`.`id`) " .
"LEFT JOIN `cake_test_db`.`users` AS `User` ON (`TestModel9`.`id` = `User`.`test_id`)";
$test->expects($this->at(0))->method('execute')
->with($this->stringContains($search));
$test->read($this->Model, array(
'joins' => array(
array(
'table' => 'users',
'alias' => 'User',
'type' => 'LEFT',
'conditions' => array('TestModel9.id = User.test_id')
)
),
'recursive' => 1
));
}
/**
* testGenerateInnerJoinAssociationQuery method
*