5. The Model

In Buan, a Model is an object that corresponds to a single record in a database table. For every table you create, you should also create a corresponding Model class.

Class location

You must create a Model class within either the [app.dir.models], [core.dir.models] or [ext.*.dir.models] folder, name it using the UpperCamelCaps convention and always suffix with the word Model. For example:

[app.dir.models]/BookModel.php
[app.dir.models]/ProductCategoryModel.php

Class structure

The basic structure of a Model class is as follows:

<?php
/* Placed in, for example, [app.dir.models]/BlogModel.php */

class BlogModel extends Model {

	protected $dbConnectionName = 'default';	/* optional, defaults to 'default' */

	protected $dbTableName = 'blog';		/* optional, defaults to lower_underscored version of class name minus 'Model' suffix */

	protected $dbTablePrimaryKey = 'id';		/* optional, defaults to 'id' */
}
?>

Here we've defined a Model that will handle entries in the blog database table, which are indexed by the primary key column id.

The blog table can be found in the database that is defined in the default connection.

Naming Conventions

When it comes to naming your Models and databases, the only restriction that you must adhere to is that your Model names and classes must use the UpperCamelCaps naming convention.

For example, for a Model named BlogEntry:

# Model name
BlogEntry

# Model class filename and definition
BlogEntryModel.php
class BlogEntryModel extends Model {
	...
}

# ModelManager class filename and definition
BlogEntryManager,php
class BlogEntryManager extends ModelManager {
	...
}

2.2.2 The ModelManager

Every Model has an associated ModelManager, the primary role of which is to handle all CRUD (Create, Replace, Update and Delete) operations associated with that Model. This allows you to keep the Model classes themselves very lightweight, because all the heavy database operations are handled by singleton instances of the ModelManagers.

A single ModelManager instance handles CRUD operations for every instance of it's associated Model.

For example:

// Create the Model instance
$m = Model::create('Invoice');

// Load a row from the database using the primary key, 'id'
$m->id = 75;
$m->getModelManager()->load($m);

// Make some changes and save back to the database
$m->amount = 56.00;
$m->getModelManager()->save($m);

// Delete the row form the database
$m->getModelManager()->delete($m);

You're probably thinking this code looks very long-winded, and you'd be right. The reason all boils down to how Buan handles in-memory Model instances, their relationships (1:M, M:M, etc) and the way it propagates instance replacements. This is all encompassed within the ModelTracker class.

2.2.3 The ModelTracker

You can think of the ModelTracker as an in-memory repository of previously loaded Model instances, which is globally accessible. The ideas behind it:

  • You can load Model A from multiple loctions within your application, knowing that each instance is actually referencing the same instance in the ModelTracker. The primary goal here is to keep a Model's list of loaded relations "fresh" across the whole application.
  • Previous point has side effect of reducing memory usage in cases of Models being loaded multiple times.

[TODO: Option to turn this off?]