Planning your Model Structure
Object oriented model structure offers you several strategies which can help you structure your application models in a most appropriate way, depending on your application type.
Standard (Organic) Database
Starting from just a few tables your database is going to grow into 30+ table database, where new tables are designed to offer data storage for a newly added features. The base tables are also getting additional fields. That's the most common way to have your database organized and I will focus on this strategy mostly in this book.
With Software as a Service websites specifically you would want to separate table data based on the owner of the data. The general business rule says that only owner of the organization is allowed to access data. Example would be a bookkeeping, invoicing, team tracking or similar system containing variety of primary data.
In this situation it makes sense to create a table "system" and associate all sensitive data with the appropriate system through 'system_id' field. Create a class 'Model_Private' which would extend 'Model_Table' just to introduce a system_id field and a condition on a model level. All the sensitive tables can then be inherited from this model. This will offer you a good security model immune to developer mistakes. Owner of system with id=1 won't be able to create a record in any private table with incorrect system_id.
Data ACLs (Access Control Lists)
In this scenario a certain data entries are available to some users as defined in the intermediate table. A good strategy here is to define a Controller which would build the necessary joins between the primary table and the ACL tables. Join condition requirements would automatically limit records available to a user only to these having a proper access record.
In this case adding data might be tricky and might require a different model.
If users are not permitted to edit certain data, it's a good idea to add additional conditions for the use of model's save() function or register beforeSave hook. That would ensure that only privileged users can update data. Even if developer working on UI presentation would accidentally expose CRUD with the read-only table, users will receive a message when trying to save data. That's not desirable but is an great additional security measure.
Sometimes you'll have a primary table ("obj") complimented with supplementary tables to compliment it depending on object type. This allows you have a common "header" of each record in a single table. Depending on the type, you can then load additional data from an additional table.
The challenge here is most efficient way for loading the data. If you know which type of data you are willing to load, you can have a model with a pre-defined join. If you only have ID of an generic object you will need to load it first to understand the type and then load data from related entry. You can use several techniques here such as model encapsulation or you can also extend the SQL_Relation class to handle your needs.
Conclusion on General Structure Selection
Agile Toolkit can handle any database structure described above or other data structure. For relational models one table is always "primary". This table requires you to have unique identifier (which is "id" by default, but can be changed).
Methods and Testing
Like any other object, your models can have a custom methods. Because Agile Toolkit does not build models for you, you can just open your favorite text editor, define a class and also add all the necessary models inside it. It's advisable that you perform a type-hinting inside your model function. You should also perform all the necessary validations and throw PHP exceptions if any errors occurs. Avoid assuming too much about the application, user interface or views which will be using your model.
Avoid creating methods which do not provide much of a functionality in themselves, such as "createRecord(array $data)". Such a functionality exists if you call set($array)->save() sequence. Another unnecessary method would be $user->getUserOrders(). A typical Agile Toolkit approach is to define relationship and use $user->ref('Order');
DVD Rental Example
The example which i'll be returning back throughout this article is a DVD rental application. The goal of the application is to build on-line application which can be used by the staff of a DVD rental shop to catalogue their movies, DVDs and clients. Clients also can log-on to the site, browse available DVDs and order them.
I will keep the development of the application as "agile" as possible and will only implement features and objects which I require to complete my immediate task.
The Source Code
The below source code creates the four basic models for our DVD Rental application.
Additionally code include a simple interface allowing the editing of the database data.
Conclusion so far
Let me wrap this page up by saying — business models are fundamental part of your application. If you are experienced web developer no doubt you have already seen the model concept. Agile Toolkit Models are different and they hide some great advantages. I will go through on the next page