Fixing ability to specify select fields for join models, and adding tests

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6230 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2007-12-23 17:03:19 +00:00
parent 6e1bacebf5
commit 0d469ac4ba
4 changed files with 81 additions and 11 deletions

View file

@ -719,10 +719,9 @@ class DboSource extends DataSource {
$query = str_replace(' WHERE 1 = 1', '', $query);
}
$with = $model->hasAndBelongsToMany[$association]['with'];
$foreignKey = $model->hasAndBelongsToMany[$association]['foreignKey'];
$habtmFields = $model->{$with}->schema();
$habtmFields = array_keys($habtmFields);
$joinKeys = array($foreignKey, $model->hasAndBelongsToMany[$association]['associationForeignKey']);
list($with, $habtmFields) = $this->getJoinModel($model, $model->hasAndBelongsToMany[$association]['with'], $joinKeys);
$habtmFieldsCount = count($habtmFields);
$q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack);
@ -1124,11 +1123,11 @@ class DboSource extends DataSource {
$joinAlias = $joinTbl;
if (isset($assocData['with']) && !empty($assocData['with'])) {
$joinFields = $model->{$assocData['with']}->schema();
$joinFields = array_keys($joinFields);
$joinKeys = array($assocData['foreignKey'], $assocData['associationForeignKey']);
list($with, $joinFields) = $this->getJoinModel($model, $assocData['with'], $joinKeys);
if (is_array($joinFields) && !empty($joinFields)) {
$joinFields = $this->fields($model->{$assocData['with']}, $model->{$assocData['with']}->alias, $joinFields);
$joinAssoc = $joinAlias = $model->{$assocData['with']}->alias;
$joinFields = $this->fields($model->{$with}, $model->{$with}->alias, $joinFields);
$joinAssoc = $joinAlias = $model->{$with}->alias;
} else {
$joinFields = array();
@ -1158,6 +1157,24 @@ class DboSource extends DataSource {
}
return null;
}
/**
* Gets the name and fields to be used by a join model. This allows specifying join fields in the association definition.
*
* @param object $model The model to be joined
* @param mixed $with The 'with' key of the model association
* @param array $keys Any join keys which must be merged with the keys queried
* @return array
*/
function getJoinModel($model, $assoc, $keys = array()) {
if (is_string($assoc)) {
return array($assoc, array_keys($model->{$assoc}->schema()));
} elseif (is_array($assoc)) {
$with = key($assoc);
return array($with, array_unique(array_merge($assoc[$with], $keys)));
} else {
trigger_error(sprintf(__('Invalid join model settings in %s', true), $model->alias), E_USER_WARNING);
}
}
function buildJoinStatement($join) {
$data = array_merge(array(
@ -1166,6 +1183,7 @@ class DboSource extends DataSource {
'table' => 'join_table',
'conditions' => array()
), $join);
//pr($data);
if (!empty($data['alias'])) {
$data['alias'] = $this->alias . $this->name($data['alias']);
@ -1173,6 +1191,7 @@ class DboSource extends DataSource {
if (!empty($data['conditions'])) {
$data['conditions'] = trim($this->conditions($data['conditions'], true, false));
}
//pr($data);
return $this->renderJoinStatement($data);
}

View file

@ -715,6 +715,9 @@ class Model extends Overloadable {
if (isset($this->{$type}[$assocKey]['with']) && !empty($this->{$type}[$assocKey]['with'])) {
$joinClass = $this->{$type}[$assocKey]['with'];
if (is_array($joinClass)) {
$joinClass = key($joinClass);
}
$plugin = null;
if (strpos($joinClass, '.') !== false) {

View file

@ -371,8 +371,21 @@ class ModelC extends CakeTestModel {
var $hasMany = array('ModelD');
}
class ModelD extends CakeTestModel {
var $name = 'ModelD';
var $useTable = 'threads';
}
class Something extends CakeTestModel {
var $name = 'Something';
var $hasAndBelongsToMany = array('SomethingElse' => array('with' => array('JoinThing' => array('doomed'))));
}
class SomethingElse extends CakeTestModel {
var $name = 'SomethingElse';
var $hasAndBelongsToMany = array('Something' => array('with' => 'JoinThing'));
}
class JoinThing extends CakeTestModel {
var $name = 'JoinThing';
var $belongsTo = array('Something', 'SomethingElse');
}
class Portfolio extends CakeTestModel {
var $name = 'Portfolio';
var $hasAndBelongsToMany = array('Item');
@ -443,7 +456,7 @@ class ModelTest extends CakeTestCase {
'core.project', 'core.thread', 'core.message', 'core.bid',
'core.portfolio', 'core.item', 'core.items_portfolio', 'core.syfile', 'core.image',
'core.device_type', 'core.device_type_category', 'core.feature_set', 'core.exterior_type_category', 'core.document', 'core.device', 'core.document_directory',
'core.primary_model', 'core.secondary_model'
'core.primary_model', 'core.secondary_model', 'core.something', 'core.something_else', 'core.join_thing'
);
function start() {
@ -535,6 +548,41 @@ class ModelTest extends CakeTestCase {
unset($this->Project);
}
function testWithAssociation() {
$this->model =& new Something();
$result = $this->model->SomethingElse->find('all');
$expected = array(
array('SomethingElse' => array('id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
'Something' => array(array('id' => '3', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
'JoinThing' => array('id' => '3', 'something_id' => '3', 'something_else_id' => '1', 'doomed' => '1', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')))),
array('SomethingElse' => array('id' => '2', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
'Something' => array(array('id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
'JoinThing' => array('id' => '1', 'something_id' => '1', 'something_else_id' => '2', 'doomed' => '1', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31')))),
array('SomethingElse' => array('id' => '3', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
'Something' => array (array('id' => '2', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
'JoinThing' => array('id' => '2', 'something_id' => '2', 'something_else_id' => '3', 'doomed' => '0', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31')))));
$this->assertEqual($result, $expected);
$result = $this->model->find('all');
$expected = array(
array('Something' => array('id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
'SomethingElse' => array(
array('id' => '2', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
'JoinThing' => array('doomed' => '1', 'something_id' => '1', 'something_else_id' => '2')))),
array('Something' => array('id' => '2', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
'SomethingElse' => array(
array('id' => '3', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
'JoinThing' => array('doomed' => '0', 'something_id' => '2', 'something_else_id' => '3')))),
array('Something' => array('id' => '3', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
'SomethingElse' => array(
array('id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
'JoinThing' => array('doomed' => '1', 'something_id' => '3', 'something_else_id' => '1')))));
$this->assertEqual($result, $expected);
}
function testFindAllRecursiveSelfJoin() {
$this->model =& new Home();
$this->model->recursive = 2;