Thinking about the model also forced me to think about the way I use and write models. This changed quite a bit over time.

At the beginning of my time with CakePHP I used to write “skinny” models, i.e. they only contained association definitions and some validation rules, and nothing else. Everything was done in the controller using the methods provided by the Model class.

In the meantime I follow the “skinny controller, fat model” principle, and so a lot of the logic I previously did in the controller is now done in the model. A side effect of this is that I tend to no longer use certain methods like Model::findAll() in my controllers. For example, if I had to write some functionality to retrieve the 10 most recent posts I would have written it in the past like:

$this->Post->findAll(array('Post.is_published' => true), null, array('Post.published DESC'), 10);

This works fine. But it is “difficult” to read as this snippet doesn’t communicate very well what I try to accomplish. The “problem” is that the “findAll” method is too generic.

By moving this snippet to its own model method we can write code that’s much easier to read and understand:

// in app/models/post.php
function findMostRecent($limit = 10) {
    return $this->findAll(array('Post.is_published' => true), null, array('Post.published DESC'), $limit);
}

// and here how we use it from our controller(s)
$this->Post->findMostRecent();

By writing such custom methods the way you use the functionality provided by the Model class changes. Many of its methods become helper methods you use from within the models, but outside the models they are no longer important.

I think it is a good idea — the next time you use one of the generic Model methods — to ask yourself: “Does this code communicate well what I try to accomplish?” And if the answer is “no”, to write a custom method.