Search code examples
cakephpcakephp-3.7

Cakephp3 doesn't recognize the table with different name in deep associations


I have created a table called Delegates, and I created a UsersTable and User Entity. And I have used $this->setTable('delegates'); in UsersTable to be able to access Delegates from $this->Users; (I just want to say I have created a User Model with delegates table)

So far so good...

In my application I am trying to access deep associations. Every thing is fine with this query but when I contain the User model I get The Users association is not defined on Comments.

I can confirm the associations are set correctly.

...
// There are more associations up there. 
...
'Comments', [
        'className' => 'App\Model\Table\CommentsTable',
        'foreignKey' => 'delegate_assessment_criteria_id',
        'belongsTo' => [
            'Assessors' => [
                'className' => 'App\Model\Table\AssessorsTable',
                'foreignKey' => 'assessor_id',
            ],
            'Users' => [
                'className' => 'App\Model\Table\UsersTable',
                'foreignKey' => 'delegate_id',
            ]
        ]
    ]

Here is deep association.

...
// There are more associations up there. 
...
'Comments' => function($q) {
    return $q
        ->select([
            'id'
        ])
        ->order(['Comments.created DESC'])  
        ->contain([
            'Assessors' => function($q) {
                return $q
                    ->select([
                        'id'
                    ])
                    ->enableAutoFields();
            }
        ])   
        ->contain([                                                                           
            'Users' => function($q) {
                return $q
                    ->select([
                        'id',
                        'delegate_id'
                    ])
                    ->enableAutoFields();
            }
        ])   
        ->enableAutoFields();
}

2 Notes:

  • If I contain the User model in very first in hierarchy of my query I can access the User fields but in deep association this doesn't work.
  • If I contain Delegates it works.

I believe there is a problem with Cakephp query builder.


Solution

  • Alright finally I figured it out. I have done it before I don't know why I forgot. Probably because I was in deep association I drained into it.

    The deep association contain was creating conflict with very first contain. if I would set different propertyName in deep associations then it does the purpose.

    Bear in mind you must set this associations on your Table Models.

    'Comments', [
            'className' => 'App\Model\Table\CommentsTable',
            'foreignKey' => 'delegate_assessment_criteria_id',
            'belongsTo' => [
                'Assessors' => [
                    'className' => 'App\Model\Table\AssessorsTable',
                    'foreignKey' => 'assessor_id',
                ],
                'Delegates' => [   //  <= Here set the name of Assossiation you want to be shown in array
                    'className' => 'App\Model\Table\UsersTable',
                    'propertyName' => 'delegates',   // <=  Add propertyName and set another name here
                    'foreignKey' => 'delegate_id',
                ]
            ]
        ]
    

    And on association

    'Comments' => function($q) {
        return $q
            ->select([
                'id'
            ])
            ->order(['Comments.created DESC'])  
            ->contain([
                'Assessors' => function($q) {
                    return $q
                        ->select([
                            'id'
                        ])
                        ->enableAutoFields();
                }
            ])   
            ->contain([                                                                           
                'Users' => function($q) {
                    return $q
                        ->select([
                            'id',
                            // 'delegate_id'  // <= Remove this - We have already done it when we set the association on above code.
                        ])
                        ->enableAutoFields();
                }
            ])   
            ->enableAutoFields();
    }