Not so obvious behavior of $uses in CakePHP
In CakePHP you declare what models you’re going to use in a controller by defining $uses variable. You can also define it in AppController to have a certain set of models available in every controller. However be careful when doing it because you may put yourself in an unexpected situation as I did recently.
I need an access to User model in beforeFilter and beforeRender actions on every request so I defined those actions in AppController along with:
$uses = array('User');
When I did this I found out that my SessionsController which handles log in and log out logic stopped working immediately. There is no Session model in the app, SessionController works with User model instead:
$uses = array('User');
The error said: “Database table sessions for model Session was not found”. So it tried to find Session model which doesn’t exist as I stated earlier. But why? I have not told Cake to include anything but User model.
To see what exactly has happened we need to look how Cake determines which models it needs to include and it’s done by merging AppController’s $uses with SessionController’s $uses. Merging is done in usual intuitive way with one exception: when SessionController’s $uses is equal to AppController’s $uses then SessionController’s “native” model (Session model here) is also loaded.
Do you have a rational explanation for such behavior? I have none. It’s very unintuitive for me.
Note that the equality of both controllers’ $uses can happen in two situations:
- both controllers have $uses defined explicitely and they’re equal
- SessionController doesn’t have $uses defined at all and derives it from AppController (parent)
When SessionController is (===) null or false no models are loaded at all, no mather what’s been defined in AppController.
