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
                                        }
                                }
                        }
                }
        }

Reply via email to