Model
Overview
The data structure of a model is defined by its .aql file. The class file and the aql file are located in the models/ folder and should contain two files:
- model_name.aql
- class.model_name.php
Saving Data
You can insert/update by posting data to the following url:
/aql/save/MODELFor example, to modify an
artistmodel, you would POST the new data to/aql/save/artist.
If the fieldartist_idis POSTed, it will be an update that record. Ifartist_idis not specified, a new record will be inserted. The/aql/saveURL is usually accessed via AJAX request.Alternatively, you may use
artist::insert()or$artist->update($data).
Examples
Sample Model 'artist'
models/artist/artist.aql
artist {
name,
slug,
genre,
tour_id,
[album]s
}
city {
name as city_name
}
models/artist/class.artist.php
<?php
class artist extends Model
{
/**
* Discard cached data older than this date.
* Use this if the data structure has changed.
* @var string
*/
public static $mod_time = '2012-1-1';
/**
* Possible Errors
* @var array
*/
protected static $possible_errors = array(
'artist_already_exists' => array(
'message' => 'This artist is already in the system.'
),
'invalid_slug' => array(
'message' => 'Invalid slug.'
)
);
/**
* Required Fields
* This model will not save if these fields are blank
* @var array
*/
public $_required_fields = array(
'name' => 'Artist name',
'slug' => 'Artist slug'
);
/**
* Read-only Fields
* Specifies which fields in the aql are read-only
* @var array
*/
public $_ignore = array(
// this means that fields in the city table cannot be saved
'tables' => array('city')
);
/**
* Foreign Keys
* If this object has a foreign key that is used to determine a list
* in a different model, then add the foreign models here so the foreign
* list is refreshed when this model's foreign key changes.
* @var array
*/
public $_belongs_to = array(
// assuming there is a model 'tour' with aql:
tour {
[artist]s
}
// if this artist->tour_id changes, the tours' artist lists will be updated
'tour' => array('tour_id')
);
/**
* This runs before the required fields are checked to make sure they
* are not blank
*/
public function beforeCheckRequiredFields()
{
if (!$this->slug) {
$this->slug = slugize($this->slug);
}
}
/**
* Adds error if slug is not valid
* @param mixed $val
*/
public function validate_slug($val)
{
if ($val != slugize($val)) {
$this->addError('invalid_slug');
}
}
/**
* This runs before insert and update. If addError() is called, the save will rollback.
*/
public function validate()
{
// validation that is not specific to a single field can go here
}
/**
* This runs before insert. If addError() is called, the save will rollback.
*/
public function beforeInsert()
{
// make sure we don't insert an artist that already exists in the database
if ($this->artistAlreadyExists()) {
$this->addError('artist_already_exists');
}
}
/**
* Check if this artist name is already in the database
*/
public function artistAlreadyExists()
{
$aql = 'artist { }';
$where = array("name = '{$this->name}'");
if ($this->artist_id) {
$where[] = ' artist.id != ' . $this->artist_id;
}
if (aql::count($aql, array('where' => $where))) {
return true;
}
return false;
}
}
Sample Usage
<?
// 1. get one artist object using its numeric identifier
$artist = new artist($artist_id);
echo $artist->name;
// 2. get one artist object using its encrypted identifier
$artist_ide = encrypt($aritst_id, 'artist');
$artist = new artist($artist_ide);
echo $artist->album[0]->name;
// 3. get one artist object using a where clause
$artist = artist::getOne(array(
'where' => "artist.slug = 'jimi-hendrix'"
));
echo $artist->name;
// 4. get many artist objects using a where clause
$artists = artist::getMany(array(
'where' => "artist.genre = 'psychedelic'",
'order by' => "artist.name asc",
'limit' => 5,
'offset' => 0
));
foreach ($artists as $artist) {
echo $artist->name;
}
// 5. get many artist_id's using a where clause
$artist_ids = artist::getList(array(
'where' => "artist.genre = 'psychedelic'",
'order by' => "artist.name asc"
));
foreach ($artist_ids as $artist_id) {
$artist = new artist($artist_id);
echo $artist->name;
}
// 6. get many artist_id's using a where clause
$artist_ids = artist::getList(array(
'where' => "artist.genre = 'psychedelic'",
'order by' => "artist.name asc"
));
Model Configuration Properties
You must define these properties in every class that extends Model:
- $possible_errors (static) -- array of possible errors
- $mod_time (static) -- discard cached data older than this date/time
- $_ignore -- array of properties that are read-only
- $_required_fields -- array of required fields
- $_belongs_to -- list of models that have a collection of this model (to refresh the cached list of ids)
User Defined (Abstract) Methods
You must define these methods without any parameters in every class that extends Model:
- construct()
- beforeCheckRequiredFields()
- validate()
- validate_FIELD()
- beforeInsert()
- beforeUpdate()
- beforeDelete()
- afterInsert()
- afterUpdate()
- afterDelete()
Static Methods
- insert() -- save a new data object
- getOne() -- get a single data object
- getMany() -- get an array of data objects
- getList() -- get an array of id's
- count() -- get the quantity of objects
- getPartial() -- get a single data object without sub-models (unless specified)
- refreshCache() -- refresh cached object (see also reload)
Methods
- update() -- update associative array of properties (same as saveProperties())
- save() -- saves current data state to the database Not recommended. Use with caution!
- delete() -- sets active = 0, deletes from memcache
- addError() -- used in validation so you can return multiple validation errors
- error() -- stop execution immediately with the specified error code
- getID()
- getIDE()
- mapSubObjects() -- array map for an array property
- dataToArray() -- returns data (objects and array objects) in array form
- getToken() -- only needed if posting to
/aql/save/MODEL - getModelName()
- getPrimaryTable()
- loadArray() (orm->set())
- loadDB() -- gets data object from memcache, or DB if necessary (writes to memcache if from DB)
- loadJSON() -- sets object data
- reload() -- reloads object data from DB, sets memcache (see also refreshCache)
- runValidation() -- executes validation methods
