Error getting the associated data in a query inside a custom class. CakePHP 3.x

I´m trying to load the associated data in a query within my custom class CstmGroupsClass, but I get the error “The Books association is not defined on Libraries”. The only way it works is writing loadModel(‘CstmLibraries’) in the controller and changing the alias to the relationships of the models to the originals, for example hasMany(‘Books’,…) to hasMany(‘CstmBooks’,…). But I need to be able to execute the query inside the custom class and in it I can´t use loadModel() and tableRegistry does not solve the problem.

Thanks for the help.

CstmGroupsClass.php

class CstmGroupsClass {

    protected $CstmGroups;

    function __construct() {        
        $this->CstmGroups = TableRegistry::get('CstmGroups');
    }

    public function listGroups($contain = []) { //Value of $contain: ['Libraries','Libraries.Books']       
        $listGroups = $this->CstmGroups->find()->contain($contain);
        return $listGroups->execute(); /* <= Here the error is produced */       
    }
}

CstmGroupsController.php

class CstmGroupsController extends AppController {

    private $cstmGroupsClass;

    public function initialize() {  
        $this->cstmGroupsClass = new CstmGroupsClass();
    }

    public function listGroups() {

        $responseListGroups = $this->cstmGroupsClass->listGroups(['Libraries','Libraries.Books']);

        $this->set(compact('responseListGroups'));
    }
}

CstmGroupsTable.php

class CstmGroupsTable extends Table {

    public $prefix = 'cstm_';

    public function initialize(array $config) {
        parent::initialize($config);

        $this->setTable($this->prefix.'groups'); //final name: cstm_groups
        $this->setPrimaryKey('id');

        $this->hasOne('Libraries', [
            'className' => $this->prefix.'libraries', //final name: cstm_libraries
            'foreignKey' => 'group_id'
        ]);
    }
}

CstmLibrariesTable.php

class CstmLibrariesTable extends Table
{
    public $prefix = 'cstm_';

    public function initialize(array $config){
        parent::initialize($config);

        $this->setTable($this->prefix.'libraries'); //final name: cstm_libraries
        $this->setPrimaryKey('id');

        $this->hasOne('Groups',[
            'className' => $this->prefix.'groups', //final name: cstm_groups
            'foreignKey' => 'library_id'
        ]);

        $this->hasMany('Books', [
            'className' => $this->prefix.'books', //final name: cstm_books
            'foreignKey' => 'library_id'
        ]);
    }
}

CstmBooksTable.php

class CstmBooksTable extends Table {

    public $prefix = 'cstm_';

    public function initialize(array $config) {
        parent::initialize($config);

        $this->setTable($this->prefix.'books'); //final name: cstm_books
        $this->setPrimaryKey('id');

        $this->belongsTo('Libraries', [
            'className' => $this->prefix.'libraries', //final name: cstm_libraries
            'foreignKey' => 'library_id'
        ]);
    }
}

May I recommend using a Component for the CstmGroupsClass instead (it’ll be named CstmGroupsComponent)?
It won’t solve the problem but it’ll look a lot sleeker down the road and also hangs on to the conventions we use :slight_smile:

also, I advice against using “soft-coded” names for classes (so don’t use the $prefix things).

In the listGroups method, you can add the following line (preferably as the first line in the method) to see whether your model has the right stuff loaded (maybe, for whatever reason):

dd($this->cstmGroups);
1 Like

I´ve found the error, the className must be written in CamelCase. I’m going to consider changing the class to a component and writing the table names without using “soft-coded” names.

Thanks for your help

1 Like