Hey Nate & all,
> > This isn't currently supported per-se, but it is a feature we're
> > working on for 1.2. What you can do in the meantime is create another
> > model for your join table, and use recursive associations to fetch the
> > data beneath the join model.
Do I define hasMany and belongsTo associations for the join-table-model ?
Is there an example somewhere (or could you give me one).
Any consequences for save() etc ?
In the meantime, i've also hacked a bit on __mergeAssociation in
cake/libs/model/datasources/dbo_source.php.
See the attached file (it's small enough to skip diff -urN)
Here's an edited version of it's comments:
Let there exist a HABTM association between two models.... :)
The join table has two foreign keys _and_ some extra column(s), e.g.:
CREATE TABLE authors_posts (
type INTEGER DEFAULT 0,
author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE,
post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
PRIMARY KEY(author_id, post_id, type)
);
CAKE won't retrieve the 'type' column, not even with $recursive set.
This seems to be intentional.
Nor will it work with a custom finderSql like:
SELECT "authors"."name", "authors_posts"."type"
FROM "authors"
JOIN "authors_posts" ON "author_id"={$__cakeID__$}
AND "post_id"="posts"."id";
(let alone: SELECT "authors"."*", "authors_posts"."type")
We have to explicitely list _all_ columns and (re)name them with AS, e.g.:
SELECT "authors"."name" AS "Author__name",
"authors_posts"."type" AS "Author__type"
I would like to skip listing all columns and (re)naming with AS.
This simplifies the finderQuery a lot and permits:
SELECT "authors"."*", "authors_posts"."type" AS authors_posts__type
FROM "authors"
JOIN "authors_posts" ON "author_id"={$__cakeID__$}
AND "post_id"="posts"."id";
I can't get at parameters in assocData or such, so can't make this
optional. Hence, this fix might break stuff in interesting ways like
(overlapping) namespaces since i don't have any in-depth knowledge on the
design issues regarding __mergeAssociation.
Albert
********** *END ENCRYPTED or SIGNED PART* **********
/**
* Enter description here...
*
* @param unknown_type $data
* @param unknown_type $merge
* @param unknown_type $association
* @param unknown_type $type
*/
/*
!!AJS
Let there exist a HABTM association between two models.... :)
The join table has two foreign keys _and_ some extra column(s), e.g.:
CREATE TABLE authors_posts (
type INTEGER DEFAULT 0,
author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE,
post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
PRIMARY KEY(author_id, post_id, type)
);
CAKE won't retrieve the 'type' column, not even with $recursive set.
Nor will it work with a custom finderSql like:
SELECT "authors"."name", "authors_posts"."type"
FROM "authors"
JOIN "authors_posts" ON "author_id"={$__cakeID__$}
AND "post_id"="posts"."id";
(let alone: SELECT "authors"."*", "authors_posts"."type")
We have to explicitely list _all_ columns and (re)name them with AS, e.g.:
SELECT "authors"."name" AS "Author__name",
"authors_posts"."type" AS "Author__type"
And i would like a way to get around that :-)
Hence... var_dump($merge) ($merge = $fetch in method queryAssociation())
teaches me that the difference is:
[0]=>
array(1) {
["Author"]=>
array(2) {
["name"]=>
versus:
[0]=>
array(1) {
[0]=>
array(2) {
["name"]=>
($a = &$merge[0]; reset($a); list($k,$v) = each($a);
if (is_int($k)) echo "(int)k=$k, v=$v<br/>\n";
else echo "(string)k=$k, v=$v<br/>\n")
This I detect and fix with splitting $association ($save/$dataAssociation)
(i can't get at parameters in assocData or such, so can't make this
optional. Hence, this fix might break stuff in interesting ways like
(overlapping) namespaces since i don't have any in-depth knowledge on the
design issues regarding this method)
*/
function __mergeAssociation(&$data, $merge, $association, $type) {
if (isset($merge[0]) && !isset($merge[0][$association])) {
$saveAssociation = $association; // !!AJS FIX
$association = Inflector::pluralize($association);
}
if ($type == 'belongsTo' || $type == 'hasOne') {
if (isset($merge[$association])) {
$data[$association] = $merge[$association][0];
} else {
if (count($merge[0][$association]) > 1) {
foreach($merge[0] as $assoc => $data2) {
if ($assoc != $association) {
$merge[0][$association][$assoc] = $data2;
}
}
}
$data[$association] = $merge[0][$association];
}
} else {
if (!isset($merge[0][$association])) { // !!AJS FIX
$dataAssociation = $saveAssociation;
$association = 0;
} else $dataAssociation = $association;
if ($merge[0][$association] === false) {
$data[$dataAssociation] = array(); // !!AJS FIX
} else {
foreach($merge as $i => $row) {
if (count($row) == 1) {
$data[$dataAssociation][] =
$row[$association]; // !!AJS FIX
} else {
$tmp =
array_merge($row[$association], $row);
unset($tmp[$association]);
$data[$dataAssociation][] =
$tmp; // !!AJS FIX
}
}
}
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Cake
PHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/cake-php
-~----------~----~----~----~------~----~------~--~---
/**
* Enter description here...
*
* @param unknown_type $data
* @param unknown_type $merge
* @param unknown_type $association
* @param unknown_type $type
*/
/*
!!AJS
Let there exist a HABTM association between two models.... :)
The join table has two foreign keys _and_ some extra column(s), e.g.:
CREATE TABLE authors_posts (
type INTEGER DEFAULT 0,
author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE,
post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
PRIMARY KEY(author_id, post_id, type)
);
CAKE won't retrieve the 'type' column, not even with $recursive set.
Nor will it work with a custom finderSql like:
SELECT "authors"."name", "authors_posts"."type"
FROM "authors"
JOIN "authors_posts" ON "author_id"={$__cakeID__$}
AND "post_id"="posts"."id";
(let alone: SELECT "authors"."*", "authors_posts"."type")
We have to explicitely list _all_ columns and (re)name them with AS, e.g.:
SELECT "authors"."name" AS "Author__name",
"authors_posts"."type" AS "Author__type"
And i would like a way to get around that :-)
Hence... var_dump($merge) ($merge = $fetch in method queryAssociation())
teaches me that the difference is:
[0]=>
array(1) {
["Author"]=>
array(2) {
["name"]=>
versus:
[0]=>
array(1) {
[0]=>
array(2) {
["name"]=>
($a = &$merge[0]; reset($a); list($k,$v) = each($a);
if (is_int($k)) echo "(int)k=$k, v=$v<br/>\n";
else echo "(string)k=$k, v=$v<br/>\n")
This I detect and fix with splitting $association ($save/$dataAssociation)
(i can't get at parameters in assocData or such, so can't make this
optional. Hence, this fix might break stuff in interesting ways like
(overlapping) namespaces since i don't have any in-depth knowledge on the
design issues regarding this method)
*/
function __mergeAssociation(&$data, $merge, $association, $type) {
if (isset($merge[0]) && !isset($merge[0][$association])) {
$saveAssociation = $association; // !!AJS FIX
$association = Inflector::pluralize($association);
}
if ($type == 'belongsTo' || $type == 'hasOne') {
if (isset($merge[$association])) {
$data[$association] = $merge[$association][0];
} else {
if (count($merge[0][$association]) > 1) {
foreach($merge[0] as $assoc => $data2) {
if ($assoc != $association) {
$merge[0][$association][$assoc] = $data2;
}
}
}
$data[$association] = $merge[0][$association];
}
} else {
if (!isset($merge[0][$association])) { // !!AJS FIX
$dataAssociation = $saveAssociation;
$association = 0;
} else $dataAssociation = $association;
if ($merge[0][$association] === false) {
$data[$dataAssociation] = array(); // !!AJS FIX
} else {
foreach($merge as $i => $row) {
if (count($row) == 1) {
$data[$dataAssociation][] =
$row[$association]; // !!AJS FIX
} else {
$tmp =
array_merge($row[$association], $row);
unset($tmp[$association]);
$data[$dataAssociation][] =
$tmp; // !!AJS FIX
}
}
}
}
}