2015-05-23 25 views
14

Sto usando CakePHP 3.x.Come unire più tabelle utilizzando CakePHP 3?

Quello che voglio è poter chiamare $ this-> Categories-> find() e quindi unire Argomenti su Topics.cat_id = Categories.id e quindi unire Post su Posts.topic_id = Topics.id.

Non ricevo errori, ma gli unici dati che sto recuperando sono i dati delle Categorie, ho provato a far entrare LEFT e INNER senza successo. Qualsiasi aiuto sarebbe molto apprezzato.

Le relazioni tra le tabelle sono:

CategoriesTable

$this->hasMany('Topics'); 

TopicsTable

$this->belongsTo('Categories'); 
$this->hasMany('Posts'); 

PostsTable

$this->belongsTo('Topics'); 

anche l'interrogazione che ho:

$query = $this->Categories->find('all') 
     ->order(['Categories.name' => 'ASC']) 
     ->join([ 
      'topics' => [ 
       'table' => 'Topics', 
       'type' => 'LEFT', 
       'conditions' => 'topics.Cat_id = Categories.id' 
      ], 
      'posts' => [ 
       'table' => 'Posts', 
       'type' => 'LEFT', 
       'conditions' => 'posts.topic_id = topics.id' 
      ] 
     ]); 

provato ad utilizzare il comportamento contenibile, ma ora sto ottenendo l'errore "Categorie non è associato a messaggi" utilizzando questa query:

$query = $this->Categories->find('all') 
     ->order(['Categories.name' => 'ASC']) 
     ->contain(['Topics', 'Posts' => function($q){ 
      return $q->where(['Posts.topic_id' => 'Topics.id']); 
     }]); 
+1

Cerca contenitori, non join manuali. ** http: //book.cakephp.org/3.0/en/orm/query-builder.html#loading-associations** – ndm

+1

@ndm Grazie per la risposta. Ho aggiornato la mia domanda con i risultati utilizzando i contenimenti, eventuali suggerimenti? – Wisd0m

+1

Dai un'occhiata più da vicino a come definire le associazioni annidate. – ndm

risposta

16

Con la consulenza @ndm dato che ero in grado di ottenere il risultato che volevo. Devo aver trascurato la sezione dei documenti, quindi chiunque altro abbia questo problema, ecco come farlo.

$query = $this->Categories->find('all') 
     ->order(['Categories.name' => 'ASC']) 
     ->contain([ 
      'Topics.Posts.Users' 
     ]); 
+0

-> contiene (['' Topics.Posts.Users ' Non avevo idea che tu potessi farlo, ho passato un giorno intero a cercare di capirlo. –

+0

Tu risparmi la mia giornata! Grazie –

-3

provare questo:

$query = $this->Categories->find('all') 
     ->fields('Categories.*', 'Topics.*', 'Posts.*') 
     ->order(['Categories.name' => 'ASC']) 
     ->join([ 
      'topics' => [ 
       'table' => 'Topics', 
       'type' => 'LEFT', 
       'conditions' => 'topics.Cat_id = Categories.id' 
      ], 
      'posts' => [ 
       'table' => 'Posts', 
       'type' => 'LEFT', 
       'conditions' => 'posts.topic_id = topics.id' 
      ] 
     ]); 

Aggiungi questa linea:

->fields('Categories.*', 'Topics.*', 'Posts.*') 

per recuperare dati da Argomenti e Messaggi

+4

Questo non funzionerà per molti ragioni, non esiste un metodo chiamato 'fields()', la scelta dei campi avviene tramite 'select()', tuttavia '. *' non è supportato dal generatore di query ORM, sarà aliasato e genererà SQL non valido, anche campi aggiuntivi su associazioni non contenute non saranno idratati e otterrete risultati duplicati in quanto ci sono relazioni 1: n, ecc ... – ndm

2

Basta trovare il tipo di eredità di cakephp2, è puoi ancora usare join come la vecchia versione.

$result = $this->Category->findAll(fields=>['id','Topic.id'], 'conditions'=>['Topic.name'=>'s'],'join'=>['Topic' => [ 
      'table' => 'topics', 
      'type' => 'INNER', 
      'conditions' => 'Topic.category_id = Category.id' 
     ]]); 

Trova familiare? è ancora possibile utilizzare alias come prima

Prima risposta, non sono sicuro di come funziona l'editor di codice, mi dispiace.

+0

Non sapevo che il metodo 'join()' è lì. Grazie per aver indicato. – Parixit