Pseudo models

Published on and tagged with cakephp  model

Sometimes you have some functionality which is on a conceptual level a model but doesn’t have anything in common with CakePHP’s models. An example for such a functionality could be the usage of an external API (there are different philosophies about where to place such functionality: some create components, others build a data source, and the rest puts it in the model or somewhere else). If you put it into the model, then the respective model looks like:

// app/models/example.php
class Example extends AppModel {
    public $useTable = false;

    public function doSomething() {
        // use API XY
    }
}

This works fine, the only disadvantage is that your model inherits a lot of functionality that’s of no use. To avoid that, I use in such a case what I call “pseudo models”: I place PHP classes which do not extend AppModel in the models directory. The example from above looks then like:

// app/models/example.php
class Example {
    public function doSomething() {
        // use API XY
    }
}

In the controller you can use this model like any other model (of course with the restriction that none of the methods/properties defined in AppModel and Model will be available):

$this->Example->doSomething();

Happy baking!

11 comments baked

  • David Persson

    I wonder if
    $PseudoModel = ClassRegistry::init('PseudoModel');
    will still work. Aren’t there any initialization methods called upon the created class? But nonetheless this is a nice and simple trick!

  • Kien Pham

    cool tip! thanks for sharing.

  • cakebaker

    @David, Kien: Thanks for your comments!

    @David: Yes, ClassRegistry::init(‘PseudoModel’); still works.

  • Brandon P

    Great concept but putting these classes that are NOT models in the ./models folder is incorrect, messy and will only lead to confusion!!

    I use a similar technique where I have a static “Common” class that give me access to common functionality that I use pretty much all over my app (in models, views, etc).

    I created a ‘classes’ directory within ./app/vendors (imo, a more appropriate place)

    ./app/vendors/classes/common.php

    And then included it on my bootstrap

    Then I can use it statically:

  • Brandon P

    Sry, code didnt post:

    bootstrap.php

    set_include_path(get_include_path() . PATH SEPARATOR . ../path/to/vendors/classes’ );

    require_once ‘common.php’;

    In my app:

    Common::getServerTime();

  • links for 2008-09-11 « Richard@Home

    […] Pseudo models – cakebaker Another useful tip from cakebaker. (tags: cakephp model) Posted by Richard@Home Filed in 15 […]

  • Tarique Sani

    Why do you call them pseudo-models? They are models which do not extend the app model. If these classes contain domain logic then by MVC guidelines they are Models.

    I find a whole lot of people just don’t get the point of MVC but in a reverse way ;)

    @Brandon P your example is comparing apples to oranges.

  • Martin Westin

    A very interesting area.
    I find is very difficult to categorize “communication” functionality (soap or other services for example).
    They are not really models even though they deal with a lot business logic.
    They need to partly be controllers to be abel to handle incoming requests but they ar not really controller either.
    And they are not clearly components either.

    For an app I have build that sends and receives a lot of SMS messages I ended up putting all of the above into a plugin. A controller to handle incoming requests, Models to deal with data and some logic, and a component so that any other controller can decide to send an outgoing message. I am still not happy with it though.

  • cakebaker

    @Brandon, Tarique, Martin: Thanks for your comments!

    @Brandon: Well, I think it depends on your point of view whether it is incorrect to put classes, which do not extend AppModel, in the models folder. If you say all classes in the models folder have to extend AppModel, then you are right, and it’s messy to put other classes into the models folder. On the other hand, if your point of view is on a more abstract level, then the implementation of a model is no longer important. Extending AppModel is one of many ways you could implement, for example, the Post model…

    I also use the approach you described for “helper” functionality, but personally I don’t like it. It feels wrong to me to have third-party-libraries and my own code in the same folder…

    @Tarique: Yes, you are right, the name is probably a bit unlucky :|

    @Martin: I think there is no definite answer to where you should place such functionality. Sometimes the best way is to leave Cake’s structure and to implement it in a way you think is more suitable for the task at hand.

  • powtac

    Good article, thanks for the hint.

    But some days ago I needed a wrapper for the google maps. My question then was: should I build a datasource or a AppModel-class. The features I required from google maps where: to receive the coordinates for an address. So I decided to build the wrapper as datasource (because it returns data).

    What do you think?
    Simon

  • cakebaker

    @Simon: Thanks for your comment!

    To realize it as a data source is a possible solution. In NoseRub we implemented the same functionality as a component ;-) So you see: different developers, different approaches to solve the same problem…

    In the meantime I would probably realize it as a vendor class (as there is no “libs” concept in the “app” folder). Personally, I don’t see it as a data source, because all the API does is to translate an address to coordinates: you send some data and you get back the same data in a different format. In the end it depends on what your definition of a data source is.

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License