Search code examples
cakephpinheritancemodeloverwritecakephp-bake

using custom models, inheriting from baked models in CakePHP


Community,

From other MVC-Frameworks / persistance-APIs, such as hibernate in the java world, I am aware of a best-practice mechanism to inherit from the generated model structure and use these inherited models as DAOs in your application. I especially like this approach because you can easily rebake your models after database changes to ajust the model associations without overwriting your access code (custom methods, eventcallbacks, etc.).

I could however not find anything similar for CakePHP.

What I tried so far

My first approach to achieve this was to use CakePHPs App::build() function. I Registered new plugin-directives for the baked models and controllers and replaced the default model and controller packages with my own implementation folders:

in bootstrap.php:

App::build(array(
        'BakedModel' => array(ROOT. DS . APP_DIR . '/Model/'),
        'BakedController' => array(ROOT. DS . APP_DIR . '/Controller/')
    ),
    App::REGISTER
);

App::build(array(
        'Model' => array(ROOT. DS . APP_DIR . '/Model/impl/'),
        'Controller' => array(ROOT. DS . APP_DIR . '/Controller/impl/')
    ),
    App::RESET
);

After I created my custom controllers and models in the impl-folders, importing and inheriting from the refering baked model:

my custom model:

App::uses('Inmessage', 'BakedModel');

class InmessageDao extends Inmessage {
    var $useTable = 'inmessages';
    ...
}

This works however, as long as I assign a new unique name for the custom model-classes (i.E. InmessageDao extends Inmessage). The problem with using another modelname is that all the inherited model relations do not refer to my other custom implementations but to the baked models of course. So I would need to copy and change all the relations into my custom models to make it work, which then lacks the advandage of inheriting. So I do not gaing anything here.

If I try to use an identical name for my custom models, Cake is not able to adress the different objects anymore. This approach results in a ClassNotFoundException

class Inmessage extends Inmessage {
    ...
}

So my question is:

Does anybody know if there is a way of properly inheriting models and use them instead of the baked models?

Or alternatively another way of rebaking only the model-relations and not overwriting the written code in the model classes?

Thanks in advance!

ps. I am currently running version 2.5.8.


Solution

  • I especially like this approach because you can easily rebake your models after database changes to ajust the model associations without overwriting your access code (custom methods, eventcallbacks, etc.).

    This is not how it works in CakePHP. If you change the schema the model will detect the change except you described the schema manually using Model::$_schema.

    I don't know the Java frameworks you talk but this sounds like you have a Schema class and your model extends that schema class.

    However, associations will be detected by Cake if the DB schema follows the CakePHP conventions. So you can do $User->Profile if there is a profiles table with a user_id field - even without creating the association manually. But this is not recommended.

    Or alternatively another way of rebaking only the model-relations and not overwriting the written code in the model classes?

    Also I don't see a problem to add new assocs manually, it's a matter of a few seconds. There is no need to re-bake the models over and over once you've baked them.

    If you're looking for a place to implement re-useable code take a look at Behaviors or put it in AppModel if the functionality is needed in every model in your app.

    I'm not sure if I got your whole issue right, hope this makes everything more clear.