cakephpcakephp-modelcakephp-4.xcakephp-bake

Loading a baked Plugin Model fails with "Table class for alias Data.History could not be found"


I baked a model into a plugin, but it fails to load.

What I did:

  1. Baked a model

    bin/cake bake model History --connection data --plugin Data --no-rules --no-validation --table elements_history
    

One moment while associations are detected.

Baking table class for History...

Creating file /var/www/app/plugins/Data/src/Model/Table/HistoryTable.php Wrote /var/www/app/plugins/Data/src/Model/Table/HistoryTable.php

Baking entity class for History...

Creating file /var/www/app/plugins/Data/src/Model/Entity/History.php Wrote /var/www/app/plugins/Data/src/Model/Entity/History.php

Baking test fixture for History...

Creating file /var/www/app/plugins/Data/tests/Fixture/HistoryFixture.php Wrote /var/www/app/plugins/Data/tests/Fixture/HistoryFixture.php Bake is detecting possible fixtures...

Baking test case for Data\Model\Table\HistoryTable ...

Creating file /var/www/app/plugins/Data/tests/TestCase/Model/Table/HistoryTableTest.php Wrote /var/www/app/plugins/Data/tests/TestCase/Model/Table/HistoryTableTest.php Done

  1. Loaded the newly created plugin via $this->addPlugin('Data');

  2. Verified the plugin was loaded via bin/cake plugin loaded

  3. Confirmed plugins/Data/src/Model/Table/HistoryTable.php exists

    root@debian:/var/www/app# cat plugins/Data/src/Model/Table/HistoryTable.php
    <?php
    declare(strict_types=1);
    
    namespace Data\Model\Table;
    
    use Cake\ORM\Query;
    use Cake\ORM\RulesChecker;
    use Cake\ORM\Table;
    use Cake\Validation\Validator;
    
    /**
     * History Model
     *
     * @method \Data\Model\Entity\History newEmptyEntity()
     * @method \Data\Model\Entity\History newEntity(array $data, array $options = [])
     * @method \Data\Model\Entity\History[] newEntities(array $data, array $options = [])
     * @method \Data\Model\Entity\History get($primaryKey, $options = [])
     * @method \Data\Model\Entity\History findOrCreate($search, ?callable $callback = null, $options = [])
     * @method \Data\Model\Entity\History patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
     * @method \Data\Model\Entity\History[] patchEntities(iterable $entities, array $data, array $options = [])
     * @method \Data\Model\Entity\History|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
     * @method \Data\Model\Entity\History saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
     * @method \Data\Model\Entity\History[]|\Cake\Datasource\ResultSetInterface|false saveMany(iterable $entities, $options = [])
     * @method \Data\Model\Entity\History[]|\Cake\Datasource\ResultSetInterface saveManyOrFail(iterable $entities, $options = [])
     * @method \Data\Model\Entity\History[]|\Cake\Datasource\ResultSetInterface|false deleteMany(iterable $entities, $options = [])
     * @method \Data\Model\Entity\History[]|\Cake\Datasource\ResultSetInterface deleteManyOrFail(iterable $entities, $options = [])
     *
     * @mixin \Cake\ORM\Behavior\TimestampBehavior
     */
    class HistoryTable extends Table
    {
        /**
         * Initialize method
         *
         * @param array $config The configuration for the Table.
         * @return void
         */
        public function initialize(array $config): void
        {
            parent::initialize($config);
    
            $this->setTable('elements_history');
            $this->setDisplayField('id');
            $this->setPrimaryKey('id');
    
            $this->addBehavior('Timestamp');
    
        }
    
        /**
         * Returns the database connection name to use by default.
         *
         * @return string
         */
        public static function defaultConnectionName(): string
        {
            return 'data';
        }
    }
    
  4. Added the plugin model to an arbitrary controller method:

    • either $this->loadModel('Data.History');,
    • or TableRegistry::getTableLocator()->get('Data.History');
  5. Got the error:

Table class for alias Data.History could not be found. Cake\ORM\Exception\MissingTableClassException CORE/src/ORM/Locator/TableLocator.php:245

What have I tried:

Do you know what is the issue and how to fix? I'm on CakePHP 4.2.4 and Bake 2.


Solution

  • In case of manually created plugins you need to make sure that you update your composer.json's autoloader configuration accordingly and dump the autoloader, otherwise your plugin classes cannot be found.

    For your local Data plugin that would look something like this:

    {
        // ...
        "autoload": {
            "psr-4": {
                // ...
                "Data\\": "plugins/Data/src/"
            }
        },
        "autoload-dev": {
            "psr-4": {
                // ...
                "Data\\Test\\": "plugins/Data/tests/"
            }
        }
    }
    

    and then you dump the autoloader:

    composer dumpautoload
    

    If you create your plugins using bake, it will ask you whether it should modify your composer.json, and if you allow it it will update it accordingly and dump the autoloader.

    See also