6.4. Writing Better Model Classes
Before we move on to looking at WhatWhat Status's controller code, here are a few tips for creating better models.
6.4.1. Keep All Model Logic in Model Methods
The first critical thing to remember is that even though you are using a SQLObject to wrap a database that just stores your data, your model objects are not just data-containing blobs. They are full-fledged objects with methods as well as attributes. So, in addition to storing your data, they can contain program logic. Perhaps this goes without saying, but somehow people don't seem to be used to treating their object relational mapper (ORM) classes like regular classes.
The critical thing to remember about model-viewer-controller (MVC) is that all the data, and all the rules and logic about how the data can be manipulated, ought to live in the model. The controller's job is just to tell the model about a user action and to start the methods by which the model will update itself.
The classic example of this is a checking account object with a withdrawal method. You probably want to verify that there is enough money in the account, and if there isn't, abort the transaction. But even if there is enough money in the account, you still want to update several tables:
The list could go on and on, but the point is that your model objects ought to be responsible for updating themselves, so that your controller can just say try_withdrawal(300) and not have to know about everything that needs to be done for a valid withdrawal transaction.
6.4.2. Create New Classes to Encapsulate Complex Relational Logic
Feel free to create your own classes when you need to go beyond what SQLObject gives you for free.
Another general rule: Don't have your controller check for some model state and then, depending on what you find, do any of a variety of things. When you design your code so that you can just call a method in your model, which checks whatever state needs checking and updates itself, you're much better off.
It's important that your model objects act like objects rather than just state-containing blobs.
If your model objects have methods that encapsulate the whole state+logic that is associated with your model, your controllers will be free to do what they are designed to do: handle user actions.