2010-11-29 4 views
0

Was ich habe:Contain nicht 2nd Level-Modell auswählen, mit HABTM & hasMany

"A" HABTM "C" HABTM "A" through join table "B" 
"A" hasMany "B" belongsTo "A" 
"C" is ordered by a "B" field 

Was ich will:

// result: 
[0] => array( 
    A => array(/* single model's fields I still need*/), 
    C => array(
     [0] => array(C.field1, C.field2, ... /* Model C fields*/), 
     [1] => array(C.field1, C.field2, ...) 
    ) 
) 

Was ich versucht habe:

// this gives me data I don't need: 
A->find('all', array('conditions' => array('id' => $id))) 
// result: 
[0] => array( 
    A => array(/* single model's fields I need*/), 
    B => array(/* I DON'T NEED */ 
     [0] => array(...) 
     [1] => array(/* ... etc, tons records I don't need */) 
    ), 
    C => array(
     [0] => array(C.field1, C.field2, ... /* I need these fields*/ 
      [B] => array(/* I DON'T NEED */) 
     ), 
     [1] => array(C.field1, C.field2, ... ) 
      [B] => array(/* ... etc, each has a model B I don't need ... */) 
     ) 
    ) 
) 

Mit Contain kann ich die Abfrage ziemlich viel abgeholzt, aber es ist immer noch Modell cruft verbunden:

// this is a little better 
A->find('all', array( 
    'conditions' => array('id' => $id), 
    'contain' => array('C') 
)) 
// result: 
[0] => array( 
    A => array(/* single model's fields I still need*/), 
    C => array(
     [0] => array(C.field1, C.field2, ... /* I still need Model C fields*/ 
      [B] => array(/* I still DON'T need this Model's fields */) 
     ), 
     [1] => array(C.field1, C.field2, ... 
      [B] => array(/* ... still has unneeded model B */) 
     ) 
    ) 
) 

NB1: Ich this gelesen habe, this und this aus dem Buch sowie this und this.

NB2: Ich habe auch versucht,

C->recursive = -1 // no effect 

C->unbindModel(array('hasAndBelongsToMany'=>A)) // no effect 

A->find('all', array(     // not what I want, but it's still 
    'conditions' => array('id' => $id), // odd that this doesn't filter C's 
    'contain' => array('A.B')));   // fields out. same as second result 

A->find('all', array(     // also not what I want, but it's 
    'conditions' => array('id' => $id), // weird that this doesn't filter B's 
    'contain' => array('A.B.field'))); // fields at all; 

Antwort

1

Die ContainableBehavior werden Felder automatisch zurück, die Ergebnisse auf der Karte erforderlich sind.

von einem page Zitiert, die Sie bereits gelesen:

$this->Post->find('all', array('contain' => 'Comment.author')); 

... // data returned: 

[Comment] => Array 
    (
     [0] => Array 
      (
       [author] => Daniel 
       [post_id] => 1 
      ) 
... 

Wie Sie die Kommentar-Arrays sehen können, nur das Autorenfeld enthalten (plus die post_id, die von CakePHP benötigt wird die zur Karte Ergebnisse).

Im Falle HABTM Beziehungen wird die Join-Modell mit den zugehörigen Fremdschlüssel zurückgegeben, da die a_id und c_id Felder durch Contain erforderlich sind. Mein Vorschlag ist, es einfach zu ignorieren und die Werte zu nehmen, die Sie brauchen. Wenn Sie möchten, können Sie sich vielleicht joins ansehen, weil Containable manchmal die Datenbank viele Male abfragt. Die Daten für verknüpfte Modelle werden jedoch nicht so gut wie "Verfügbar" zurückgegeben.

+0

Für diejenigen von Ihnen, die das gleiche suchen, habe ich das Array mit $ A = $ data ['A'] formatiert; $ B = Set :: classicExtract ($ Daten, 'B. {n}. {Feld1 | Feld2 | Feld3 | Feld4}'); $ data = array ( 'A' => A, 'B' => $ B ); –