0

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.

TurbuLenz
  • 45
  • 1
  • 9

2 Answers2

1

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.

floriank
  • 25,546
  • 9
  • 42
  • 66
  • I am aware of the built in mechanisms of cakes model associations from nameing naming conventions. I'm just looking for a way of easing the work on frequent database changes during the development phase. And since other frameworks offer solutions here, I thought cake might as well. Maybe it just doesn't. Thanks for your reply anyway @burzum! – TurbuLenz Feb 13 '15 at 13:10
  • What *exactly* are you missing? Can you show me an example in one of these other none php frameworks? There is a migration plugin for Cake 2 and 3 to properly change the database itself. – floriank Feb 13 '15 at 13:13
  • i.E. with "Hibernate" you generate models files (called pojo or dao) from the database similar to cakes bake-script. But you are not supposed to edit these files, instead you inherit them and make only changes in your inherited model-Classes. These inherited models are used in the application, not the generated ones. If you have any database changes then, you just regenerate and overwrite your pojos/daos and all your custom models inherit the new changes (attributes, accosiations, ...), but your custom functions remain untouched. – TurbuLenz Feb 13 '15 at 14:11
  • So if you transport this idea to cake, the pojos/daos are the baked models. I am looking for a way of extending them in another class and let the framework use these instead of the generated ones. I think it is possible to achieve this with PHP namespaces, which are not supported by cake in version 2. I was hoping someone could prove me wrong ;-) – TurbuLenz Feb 13 '15 at 14:12
  • 1
    You could create your own bake templates and let it generate another class by convention BaseModel.php put the assocs in there and modify the model template to inherit that instead of AppModel. However, I don't think this is needed for CakePHP, I think you're trying to enforce something that is not needed here because you're used to it. Like I said, adding new assocs is very simple. We haven't had a need for something like this, even in an ever growing app with ~560 tables. – floriank Feb 13 '15 at 14:16
  • You might be right, maybe I am stuck a little bit with java enterprise structures ;-) Using a custom bake-script generating my desired model structure sounds promising, I'll give that a shot. Thanks for your support @burzum! – TurbuLenz Feb 13 '15 at 14:33
  • Welcome, but be aware that this is a good amount of work you'll have to do to get this working right! – floriank Feb 13 '15 at 14:54
1

I think a simple way to do that in Cake is simple create a "plugin", store models inside that plugin and when needed you include in controllers "plugin.model".

The models can extends to bake generated models, and all other things could be inside plugin model, when you bakes, dont need to rewrite relations, validations, etc...

I hope this may help!

  • Thanks for your input in that matter. This is an interesting approach. I will try it next time. This one I solved using a _custom bake template_ for my models that creates two models, a prefixed base model containing the relations and the regular model inheriting the base model. The template also makes sure that implemented models are never overwritten. It works stable for two years now and saved me a lot of headaches. – TurbuLenz Mar 10 '17 at 12:01