Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join multiple tables using CakePHP 3?

I am using CakePHP 3.x.

What I want is to be able to call $this->Categories->find() and then join Topics on Topics.cat_id = Categories.id and then join Posts on Posts.topic_id = Topics.id.

I don't get any errors but the only data I'm getting back is the Categories data, i have tried LEFT and INNER join with no success. Any help would be greatly appreciated.

The table relationships are:

CategoriesTable

$this->hasMany('Topics');

TopicsTable

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

PostsTable

$this->belongsTo('Topics');

Also the query i have:

$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'
            ]
        ]);

Tried using the containable behavior but now i'm getting the error "Categories is not associated with Posts" using this query:

$query = $this->Categories->find('all')
        ->order(['Categories.name' => 'ASC'])
        ->contain(['Topics', 'Posts' => function($q){
            return $q->where(['Posts.topic_id' => 'Topics.id']);
        }]);
like image 822
Wisd0m Avatar asked May 23 '15 14:05

Wisd0m


2 Answers

With the advice @ndm gave i was able to get the result i wanted. I must have overlooked the section in the docs, so anyone else having this problem, here's how to do it.

$query = $this->Categories->find('all')
        ->order(['Categories.name' => 'ASC'])
        ->contain([
            'Topics.Posts.Users'
        ]);
like image 153
Wisd0m Avatar answered Nov 06 '22 09:11

Wisd0m


Just find the kind of legacy of cakephp2, you can still use join like the old version.

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

Find familiar? you still be able to use alias as before

First time answer, not sure how the code editor works, sorry.

like image 43
sambo Avatar answered Nov 06 '22 08:11

sambo