Leaning on CakePHP
There is a ton of information that CakePHP sets up for each request. Looking at the Controller object API, you can see that a sizable chunk is devoted to maintaining the data about the current request (as it should be) but what, if anything, are you doing with that information? Here's some tidbits I've ran into while developing a plugin that you can use to start "leaning on CakePHP" in your application.
One of the first things you should do for any application is to create your basic CRUD and index actions in the AppController. This give us a reliable base to build upon, helps keep things DRY and make our lives easier down the road by easily transitioning into API verbs. Here's an example of the index method...
As this is intended to go into the AppController you can see that we're using $this->modelClass to determine the controller's default model. We also don't perform any "work" if we see that it has already been done by the controller. Finally, as a bit of nice to have code we are looking in the named parameters for anything that matches a column name and automatically applying that as a condition to our pagination. This lets us easily create an address such as /posts/index/author_id:1
One thing to point out here is that this can easily be overridden by the controller. If it needs to do more than is available we can easily create an index method in the "concrete" controller and only call parent::index() if it's still usable. Let's check out another method...
[There are some custom methods defined in there that should be relatively self-explanatory] This one is pretty straight forward: The user asked us to delete something, we're going to attempt to delete it and based on the outcome give the user a textual response and possibly redirect them to the index action of the current controller.
I can already hear you saying "But... but... Joe, what if they don't have permissions to delete the record?" well, that's not the job of this method to determine. These are only methods to be built upon. Hence why they're in our AppController. Perform your authentication checks in the concrete controller and only call the parent method if everything checks out.
Alright one more now, my favorite.
[This code is extremely verbose because of the plugin's nature] Here we're leveraging on our own code. If the user hasn't sent any data we trigger our view method to get all of our view variables setup (and possibly perform authentication) before rendering. If the user has sent us data we simply toss in the ID of the record they're updating and then trigger our create method. How easy was that?
With this base of simple, straightforward CRUD methods you can save a large amount of time by reusing code and only writing modifications for specific cases.