Class \Prado\Data\ActiveRecord\TActiveRecord
An active record creates an object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
Active record objects are stateful, this is main difference between the TActiveRecord implementation and the TTableGateway implementation.
The essence of an Active Record is an object model of the domain (e.g. products, items) that incorporates both behavior and data in which the classes match very closely the record structure of an underlying database. Each Active Record is responsible for saving and loading to the database and also for any domain logic that acts on the data.
The Active Record provides methods that do the following:
- Construct an instance of the Active Record from a SQL result set row.
- Construct a new instance for later insertion into the table.
- Finder methods to wrap commonly used SQL queries and return Active Record objects.
- Update the database and insert into it the data in the Active Record.
Example:
class UserRecord extends TActiveRecord
{
const TABLE='users'; //optional table name.
public $username; //corresponds to the fieldname in the table
public $email;
//returns active record finder instance
public static function finder($className=__CLASS__)
{
return parent::finder($className);
}
}
//create a connection and give it to the ActiveRecord manager.
$dsn = 'pgsql:host=localhost;dbname=test';
$conn = new TDbConnection($dsn, 'dbuser','dbpass');
TActiveRecordManager::getInstance()->setDbConnection($conn);
//load the user record with username (primary key) 'admin'.
$user = UserRecord::finder()->findByPk('admin');
$user->email = 'admin@example.org';
$user->save(); //update the 'admin' record.
Since v3.1.1, TActiveRecord starts to support column mapping. The physical column names (defined in database) can be mapped to logical column names (defined in active classes as public properties.) To use this feature, declare a static class variable COLUMN_MAPPING like the following:
class UserRecord extends TActiveRecord
{
const TABLE='users';
public static $COLUMN_MAPPING=array
(
'user_id'=>'username',
'email_address'=>'email',
);
public $username;
public $email;
}
In the above, the 'users' table consists of 'user_id' and 'email_address' columns, while the UserRecord class declares 'username' and 'email' properties. By using column mapping, we can regularize the naming convention of column names in active record.
Since v3.1.2, TActiveRecord enhanced its support to access of foreign objects. By declaring a public static variable RELATIONS like the following, one can access the corresponding foreign objects easily:
class UserRecord extends TActiveRecord
{
const TABLE='users';
public static $RELATIONS=array
(
'department'=>array(self::BELONGS_TO, 'DepartmentRecord', 'department_id'),
'contacts'=>array(self::HAS_MANY, 'ContactRecord', 'user_id'),
);
}
In the above, the users table is related with departments table (represented by DepartmentRecord) and contacts table (represented by ContactRecord). Now, given a UserRecord instance $user, one can access its department and contacts simply by: $user->department and $user->contacts. No explicit data fetching is needed. Internally, the foreign objects are fetched in a lazy way, which avoids unnecessary overhead if the foreign objects are not accessed at all.
Since v3.1.2, new events OnInsert, OnUpdate and OnDelete are available. The event OnInsert, OnUpdate and OnDelete methods are executed before inserting, updating, and deleting the current record, respectively. You may override these methods; a TActiveRecordChangeEventParameter parameter is passed to these methods. The property \Prado\Data\ActiveRecord\TActiveRecordChangeEventParameter::setIsValid of the parameter can be set to false to prevent the change action to be executed. This can be used, for example, to validate the record before the action is executed. For example, in the following the password property is hashed before a new record is inserted.
class UserRecord extends TActiveRecord
{
function OnInsert($param)
{
//parent method should be called to raise the event
parent::OnInsert($param);
$this->nounce = md5(time());
$this->password = md5($this->password.$this->nounce);
}
}
Since v3.1.3 you can also define a method that returns the table name.
class UserRecord extends TActiveRecord
{
public function table()
{
return 'users';
}
}
Class hierarchy
Author: Wei Zhuo <weizho[at]gmail[dot]com>Since: 3.1
public
|
__call(mixed $method, mixed $args) : mixed
Dynamic find method using parts of method name as search criteria.
Method name starting with "findBy" only returns 1 record. Method name starting with "findAllBy" returns 0 or more records. Method name starting with "deleteBy" deletes records by the trail criteria. The condition is taken as part of the method name after "findBy", "findAllBy" or "deleteBy". The following are equivalent:
|
public
|
__construct([array<string|int, mixed> $data = [] ][, null|TDbConnection $connection = null ]) : mixed
Create a new instance of an active record with given $data. The record
can be saved to the database specified by the $connection object.
|
public
|
__get(string $name) : mixed
Magic method for reading properties.
This method is overriden to provide read access to the foreign objects via the key names declared in the RELATIONS array. |
public
|
__set(string $name, mixed $value) : mixed
Magic method for writing properties.
This method is overriden to provide write access to the foreign objects via the key names declared in the RELATIONS array. |
public
|
|
public
|
|
public
|
|
public
|
count([string|TActiveRecordCriteria $criteria = null ][, mixed $parameters = [] ]) : int
Find the number of records.
|
public
static
|
createRecord(string $type, array<string|int, mixed> $data) : null|TActiveRecord
Create an AR instance specified by the AR class name and initial data.
If the initial data is empty, the AR object will not be created and null will be returned. (You should use the "new" operator to create the AR instance in that case.) |
public
|
delete() : bool
Deletes the current record from the database. Once deleted, this object
can not be saved again in the same instance.
|
public
|
deleteAll([string|TActiveRecordCriteria $criteria = null ][, mixed $parameters = [] ]) : int
Delete multiple records using a criteria.
|
public
|
|
public
|
deleteByPk(mixed $keys) : int
Delete records by primary key. Usage:
For composite primary keys (determined from the table definitions):
|
public
|
equals(TActiveRecord $record[, bool $strict = false ]) : bool
Compare two records using their primary key values (all column values if
table does not defined primary keys). The default uses simple == for
comparison of their values. Set $strict=true for identity comparison (===).
|
public
|
find(string|TActiveRecordCriteria $criteria[, mixed $parameters = [] ]) : TActiveRecord
Find one single record that matches the criteria.
Usage:
|
public
|
findAll([string|TActiveRecordCriteria $criteria = null ][, mixed $parameters = [] ]) : array<string|int, mixed>
Same as find() but returns an array of objects.
|
public
|
findAllByIndex(TActiveRecordCriteria $criteria, array<string|int, mixed> $fields, array<string|int, mixed> $values) : array<string|int, mixed>
Fetches records using the sql clause "(fields) IN (values)", where
fields is an array of column names and values is an array of values that
the columns must have.
This method is to be used by the relationship handler. |
public
|
findAllByPks(mixed $keys) : array<string|int, mixed>
Find multiple records matching a list of primary or composite keys.
For scalar primary keys:
For composite keys:
|
public
|
findAllBySql(string $sql[, array<string|int, mixed> $parameters = [] ]) : array<string|int, mixed>
Find records using full SQL, returns corresponding record object.
The names of the column retrieved must be defined in your Active Record class. |
public
|
findByPk(mixed $keys) : null|TActiveRecord
Find one record using only the primary key or composite primary keys. Usage:
|
public
|
findBySql(string $sql[, array<string|int, mixed> $parameters = [] ]) : TActiveRecord
Find records using full SQL, returns corresponding record object.
The names of the column retrieved must be defined in your Active Record class. |
public
static
|
finder([string $className = __CLASS__ ]) : TActiveRecord
Returns the instance of a active record finder for a particular class.
The finder objects are static instances for each ActiveRecord class. This means that event handlers bound to these finder instances are class wide. Create a new instance of the ActiveRecord class if you wish to bound the event handlers to object instance. |
public
static
|
|
public
|
getColumnValue(string $columnName) : mixed
Retrieves the column value according to column name.
This method is used internally. |
public
|
getDbConnection() : TDbConnection
Gets the current Db connection, the connection object is obtained from
the TActiveRecordManager if connection is currently null.
|
public
|
|
public
|
|
public
static
|
getRecordManager() : TActiveRecordManager
Gets the record manager for this object, the default is to call
TActiveRecordManager::getInstance().
|
public
|
|
public
|
|
public
|
|
public
|
|
public
|
onCreateCommand(TDataGatewayEventParameter $param) : mixed
Raised when a command is prepared and parameter binding is completed.
The parameter object is TDataGatewayEventParameter of which the \Prado\Data\DataGateway\TDataGatewayEventParameter::getCommand property can be inspected to obtain the sql query to be executed. Note well that the finder objects obtained from ActiveRecord::finder() method are static objects. This means that the event handlers are bound to a static finder object and not to each distinct active record object. |
public
|
onDelete(TActiveRecordChangeEventParameter $param) : mixed
Raised before the record attempt to delete its data from the database.
To prevent the delete operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. |
public
|
onExecuteCommand(TDataGatewayResultEventParameter $param) : mixed
Raised when a command is executed and the result from the database was returned.
The parameter object is TDataGatewayResultEventParameter of which the \Prado\Data\DataGateway\TDataGatewayEventParameter::getResult property contains the data return from the database. The data returned can be changed by setting the \Prado\Data\DataGateway\TDataGatewayEventParameter::setResult property. Note well that the finder objects obtained from ActiveRecord::finder() method are static objects. This means that the event handlers are bound to a static finder object and not to each distinct active record object. |
public
|
onInsert(TActiveRecordChangeEventParameter $param) : mixed
Raised before the record attempt to insert its data into the database.
To prevent the insert operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. |
public
|
onUpdate(TActiveRecordChangeEventParameter $param) : mixed
Raised before the record attempt to update its data in the database.
To prevent the update operation, set the TActiveRecordChangeEventParameter::IsValid parameter to false. |
public
|
save() : bool
Saves the current record to the database, insert or update is automatically determined.
|
public
|
setColumnValue(string $columnName, mixed $value) : mixed
Sets the column value according to column name.
This method is used internally. |
public
|
|
public
|
setInvalidFinderResult(null|TActiveRecordInvalidFinderResult $value) : mixed
Define the way an active record finder react if an invalid magic-finder invoked
|
public
|
|
public
|
|
protected
|
createRelationContext(string $name) : null|TActiveRecordRelationContext
Gets a static copy of the relationship context for given property (a key
in $RELATIONS), returns null if invalid relationship. Keeps a null
reference to all invalid relations called.
|
protected
|
fetchResultsFor(string $property) : bool
Tries to load the relationship results for the given property. The $property
value should correspond to an entry key in the $RELATION array.
This method can be used to lazy load relationships.
|
protected
|
getRecordCriteria(string|TSqlCriteria $criteria, mixed $parameters[, array<string|int, mixed> $args = [] ]) : TSqlCriteria
Create a new TSqlCriteria object from a string $criteria. The $args
are additional parameters and are used in place of the $parameters
if $parameters is not an array and $args is an arrary.
|
protected
|
getRelationHandler(string $name[, array<string|int, mixed> $args = [] ]) : null|TActiveRecordRelation
Returns the active record relationship handler for $RELATION with key
value equal to the $property value.
|
protected
|
populateObject(array<string|int, mixed> $data) : TActiveRecord
Populates a new record with the query result.
This is a wrapper of createRecord. |
protected
|
|
private
|
|
private
|
public
mixed
|
BELONGS_TO
|
'BELONGS_TO'
|
public
mixed
|
HAS_MANY
|
'HAS_MANY'
|
public
mixed
|
HAS_ONE
|
'HAS_ONE'
|
public
mixed
|
MANY_TO_MANY
|
'MANY_TO_MANY'
|
public
mixed
|
STATE_DELETED
|
2
|
public
mixed
|
STATE_LOADED
|
1
|
public
mixed
|
STATE_NEW
|
0
|
\Prado\TComponent::GLOBAL_RAISE_EVENT_LISTENER |