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); $query = str_replace(' WHERE 1 = 1', '', $query);
} }
$with = $model->hasAndBelongsToMany[$association]['with'];
$foreignKey = $model->hasAndBelongsToMany[$association]['foreignKey']; $foreignKey = $model->hasAndBelongsToMany[$association]['foreignKey'];
$habtmFields = $model->{$with}->schema(); $joinKeys = array($foreignKey, $model->hasAndBelongsToMany[$association]['associationForeignKey']);
$habtmFields = array_keys($habtmFields); list($with, $habtmFields) = $this->getJoinModel($model, $model->hasAndBelongsToMany[$association]['with'], $joinKeys);
$habtmFieldsCount = count($habtmFields); $habtmFieldsCount = count($habtmFields);
$q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack); $q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack);
@ -1124,11 +1123,11 @@ class DboSource extends DataSource {
$joinAlias = $joinTbl; $joinAlias = $joinTbl;
if (isset($assocData['with']) && !empty($assocData['with'])) { if (isset($assocData['with']) && !empty($assocData['with'])) {
$joinFields = $model->{$assocData['with']}->schema(); $joinKeys = array($assocData['foreignKey'], $assocData['associationForeignKey']);
$joinFields = array_keys($joinFields); list($with, $joinFields) = $this->getJoinModel($model, $assocData['with'], $joinKeys);
if (is_array($joinFields) && !empty($joinFields)) { if (is_array($joinFields) && !empty($joinFields)) {
$joinFields = $this->fields($model->{$assocData['with']}, $model->{$assocData['with']}->alias, $joinFields); $joinFields = $this->fields($model->{$with}, $model->{$with}->alias, $joinFields);
$joinAssoc = $joinAlias = $model->{$assocData['with']}->alias; $joinAssoc = $joinAlias = $model->{$with}->alias;
} else { } else {
$joinFields = array(); $joinFields = array();
@ -1158,6 +1157,24 @@ class DboSource extends DataSource {
} }
return null; 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) { function buildJoinStatement($join) {
$data = array_merge(array( $data = array_merge(array(
@ -1166,6 +1183,7 @@ class DboSource extends DataSource {
'table' => 'join_table', 'table' => 'join_table',
'conditions' => array() 'conditions' => array()
), $join); ), $join);
//pr($data);
if (!empty($data['alias'])) { if (!empty($data['alias'])) {
$data['alias'] = $this->alias . $this->name($data['alias']); $data['alias'] = $this->alias . $this->name($data['alias']);
@ -1173,6 +1191,7 @@ class DboSource extends DataSource {
if (!empty($data['conditions'])) { if (!empty($data['conditions'])) {
$data['conditions'] = trim($this->conditions($data['conditions'], true, false)); $data['conditions'] = trim($this->conditions($data['conditions'], true, false));
} }
//pr($data);
return $this->renderJoinStatement($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'])) { if (isset($this->{$type}[$assocKey]['with']) && !empty($this->{$type}[$assocKey]['with'])) {
$joinClass = $this->{$type}[$assocKey]['with']; $joinClass = $this->{$type}[$assocKey]['with'];
if (is_array($joinClass)) {
$joinClass = key($joinClass);
}
$plugin = null; $plugin = null;
if (strpos($joinClass, '.') !== false) { if (strpos($joinClass, '.') !== false) {

View file

@ -371,8 +371,21 @@ class ModelC extends CakeTestModel {
var $hasMany = array('ModelD'); var $hasMany = array('ModelD');
} }
class ModelD extends CakeTestModel { class ModelD extends CakeTestModel {
var $name = 'ModelD';
var $useTable = 'threads'; 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 { class Portfolio extends CakeTestModel {
var $name = 'Portfolio'; var $name = 'Portfolio';
var $hasAndBelongsToMany = array('Item'); var $hasAndBelongsToMany = array('Item');
@ -443,7 +456,7 @@ class ModelTest extends CakeTestCase {
'core.project', 'core.thread', 'core.message', 'core.bid', 'core.project', 'core.thread', 'core.message', 'core.bid',
'core.portfolio', 'core.item', 'core.items_portfolio', 'core.syfile', 'core.image', '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.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() { function start() {
@ -535,6 +548,41 @@ class ModelTest extends CakeTestCase {
unset($this->Project); 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() { function testFindAllRecursiveSelfJoin() {
$this->model =& new Home(); $this->model =& new Home();
$this->model->recursive = 2; $this->model->recursive = 2;

View file

@ -44,9 +44,9 @@ class PostFixture extends CakeTestFixture {
'updated' => 'datetime' 'updated' => 'datetime'
); );
var $records = array( var $records = array(
array ('id' => 1, 'author_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'), array('id' => 1, 'author_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'),
array ('id' => 2, 'author_id' => 3, 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'), array('id' => 2, 'author_id' => 3, 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
array ('id' => 3, 'author_id' => 1, 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31') array('id' => 3, 'author_id' => 1, 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
); );
} }
?> ?>