Table of Contents
StatusDraft
TodoFill in missing stuff, Missing methods, __get properties, relationships

Object Relational Mapping (ORM) Library

Object Relational Mapping (ORM) provides a way create objects that represent rows from a database. It also provides a way to define and retrieve rows that are related by foreign keys. By creating relationships between models that follow convention over configuration, much of the repetition of writing queries to create, read, update and delete information from the database can be reduced or entirely removed.

It is highly recommended to use a Relational Database that supports true Foreign Keys. See Choosing A Database for further information on this topic.

To use ORM, you must first create a Model that extends ORM. Each model represents the database table, and each object created by the model represents one or more rows from that table:

class User_Model extends ORM {}

Once a model has been defined, a row can loaded from the database:

// Load the user with "id = 1"
$user = ORM::factory('user', 1);
 
// Show the user's email address
echo $user->email;

Loaded objects can also be modified and saved:

// Change the user's email address
$user->email = 'user@example.com';
 
// Show the new email address
echo $user->email;
 
// Save the change
$user->save();

Loading Models

There are two ways to load models:

// Creating a new object
$user = new User_Model(1);
 
// Using the factory method
$user = ORM::factory('user', 1);

Both work exactly the same, but the factory method is chainable, so it is preferred.

The find method can also be used to select a different row on a loaded object:

// Load the user with "id = 2"
$user->find(2);

Method Reference

All of the default public and protected methods of ORM are listed here.

factory

Static method used to load ORM objects:

$object = ORM::factory($model_name, $row_id = NULL);

find

Find executes the database query, gets one row and sets the current object to the result.

$object = ORM::factory('article');
$object->find(1);
echo $object->title;

find_all

Find_all executes a database query and returns the multiple records using the ORM_Iterator

$articles = ORM::factory('article')->find_all();
foreach($articles as $article)
{
    echo $article->title;
}

save

Save the current object into the database. If the object has no 'id' set it will insert a new record, else it will update.

$object = ORM::factory('article');
$object->find(1);
$object->title='New title';
$object->save();

delete

Delete deletes current object or object with the given id.

$article = ORM::factory('article',1);
$article->delete();
//OR
ORM::factory('article')->delete(1); //Only uses one query instead of two

as_array

Returns the current object in array format.

$article = ORM::factory('article',1);
$article=$article->as_array();
 
if(is_array($article))
{
    echo $article['title'];
}

has

add

remove

Properties Reference

loaded

Boolean for seeing whether the current object is loaded

$article = ORM::factory('article',1);
 
if($article->loaded==true)
{
    echo 'loaded';
}

saved

Boolean for seeing whether the current object is saved

$article = ORM::factory('article',1);
 
if($article->saved==false)
{
    echo 'not saved';
}
 
$article->save();
 
if($article->saved==true)
{
    echo 'saved';
}

relationships

StatusDraft

When using relationships and you want related rows, you can pull them up by accessing the relationship as a field example:

$users = $role->users;

or

$roles = $user->roles;

Choosing A Database

Kohana currently supports three databases that allow for true foreign keys: PostgreSQL, MySQL (using InnoDB tables), and MSSQL. By using one of these databases, relationship integrity is enforced at the the database level.

For example, you can create a table that will automatically delete rows when a foreign key is deleted:

-- roles_users joining table (MySQL)
CREATE TABLE roles_users (
  user_id smallint(5) UNSIGNED NOT NULL,
  role_id tinyint(3) UNSIGNED NOT NULL,
  PRIMARY KEY  (user_id,role_id),
  KEY fk_role_id (role_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
ALTER TABLE `roles_users`
  ADD CONSTRAINT roles_users_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
  ADD CONSTRAINT roles_users_ibfk_2 FOREIGN KEY (role_id) REFERENCES roles (id) ON DELETE CASCADE;

Use constraints like this will automatically delete the relationship between the user or role objects when either is deleted.

Using unique keys to construct ORM

By default, ORM will load using the id column as the identifier for the unique row within the database. However it is possible to allow ORM to load the object from other unique keys. ORM uses a method called unique_key to load data and this method can be overloaded within your ORM model to allow other columns to be used.

The example demonstrates the use of unique_key within an ORM model. The id is checked for data type. If the datatype is not a digit and is a string, the column shortname will be used to load the model.

public function unique_key($id = NULL)
{
	if ( !empty($id) && is_string($id) && !ctype_digit($id) )
	{
		return 'shortname';
	}
 
	return parent::unique_key($id);
}

If you intend to you use custom unique keys within your application, it is a good idea to ensure you correctly index all columns being used as a unique identifier. This will ensure that as your application scales, performance is not adversely effected.

Assuming the homepage record has an ID of 1, including the unique_key method within your ORM model allows the following constructor methods in your code.

// Using the ORM::factory method
$my_page = ORM::factory( 'Page', 'homepage' );
 
// Using the standard constructor
$my_other_page = new Page_Model( 'homepage' );
 
$my_old_method = new Page_Model( 1 );

$my_page, $my_other_page and $my_old_method will all contain the same record.

libraries/orm.txt · Last modified: 2008/09/02 13:00 by delapouite