This is documentation for Kohana v2.3.x.

Table of Contents
TodoFill in missing stuff on subpages, Missing methods, __get properties, clearer explanation/example of the difference between the “loaded” and “saved” properties

Object Relational Mapping (ORM) Library

Object Relational Mapping (ORM) allows manipulation and control of data within a database as though it was a PHP object. Once you define the relationships ORM allows you to pull data from your database, manipulate the data in any way you like and then save the result back to the database without the use of SQL. 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. All of the relationships can be handled automatically by the ORM library and you can access related data as standard object properties.

Table of Contents

*If you are new to ORM, start by reading the Getting Started section.

ORM's Relationship to the Database Library

The majority of ORM questions that get asked are to do with how the ORM library uses the Database library. It is important to understand that nearly all of the Database Query Builder methods are available to use on ORM objects. The only query builder methods which cannot be used are:

If you do not understand the Database library's query builder - you should start there before using ORM

ORM API Reference

Examples of the most commonly used ORM methods and properties are listed below for quick reference. Please refer to the Kohana API Documentation for a complete list of all available methods and properties.

Methods

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.

// find the article with primary key = 1
$object = ORM::factory('article')->find(1);
echo $object->title;
// find an article by title
$object = ORM::factory('article')->where('title', $title)->find();

An object is returned even if no row is found. To test the object to see if it contains a result use loaded.

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;
}

Also you can get a range of the multiple records using additional parameters (like in SQL LIMIT; note that MySQL confusingly adopts the opposite order)

$limit = 10;
$offset = 30;
//it will return 10 records started from row #30
$articles = ORM::factory('article')->find_all($limit,$offset);

where

where() is documented here.

orwhere

orwhere() is documented here.

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. Note: You need to call save() after add() and remove() to save changes to related tables.

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

Newly created objects will always be reloaded after they are saved, to properly account for default values of columns.

clear

Clears the state of an object, making it empty for reuse.

$article = ORM::factory('article', 1);
 
// Article is now empty
$article->clear();
 
var_dump($article->loaded); // returns FALSE

reload

Reloads the ORM object from the database. If $this→reload_on_wakeup is enabled, unserializing an object will cause it to be reloaded.

$article = ORM::factory('article', 1);
 
$article->title = 'A different title';
 
// Article title will be reset to the saved state
$article->reload();
 
var_dump($article->title); // returns the original title

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

delete_all

Delete_all deletes multiple objects. Will delete all objects of this type with no arguments, or an array can be used to specify the IDs to delete.

// Deletes all records
ORM::factory('article')->delete_all();
 
// Deletes records with ID 1, 2, 4, and 5
ORM::factory('article')->delete_all(array(1,2,4,5));

Delete_all can also be used to delete records based on a where clause.

//Delete all records that are part of the category of id 1
ORM::factory('article')->where(array('category_id' => 1))->delete_all();

as_array

Returns the current object in array format.

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

select_list

Generates a key/value pair array of all the objects. The function accepts two column names as parameters: the first column is the value and the second column is the name or description. This is especially useful when used in conjunction with the form helper to automatically build and populate selection menus.

The following example generates links to all articles followed by an HTML select form element pre-populated with all articles.

$articles = ORM::factory('article')->select_list('id', 'title');
 
foreach ($articles as $id => $title)
{
    // Display a list of links
    echo html::anchor('articles/'.$id, $title);
}
 
// Display a dropdown list
echo form::dropdown('articles', $articles);

has

Tests if an object has a many-to-many relationship with another object. The following code will test if the user has the login role. This method always returns a boolean.

$user = ORM::factory('user', 1);
 
//either retrieve relationship by primary primary key
$user->has(ORM::factory('role', 1));
 
// or if you have overloaded the ORM::unique_key() method in your model to allow retrieval by other unique columns
$user->has(ORM::factory('role', 'login'));

add

Adds a relationship to an object that has a many-to-many relationship. The following code will add the admin role to a user. Note that you need to call the save() method to add the relationship and related records. ORM does not automatically save your changes.

$user = ORM::factory('user', 1);
 
$user->add(ORM::factory('role', 'admin'));
 
$user->save();

Alternative syntax is also available to add multiple relationships in a many-to-many pivot table using array(id, id) syntax.

remove

Remove a relationship from an object that has a many-to-many relationship. The following code will remove the login role from the user. Note that you need to call the save() method to remove the relationship and related records. ORM does not automatically save your changes.

$user = ORM::factory('user', 1);
 
$user->remove(ORM::factory('role', 'login'));
 
$user->save();

Alternative syntax is also available to add/update multiple relationships in a many-to-many pivot table using array(id, id) syntax. Id's excluded from the array will be removed.

with

Binds a one-to-one relationship using a JOIN. This is useful in situations where you do not want to use lazy-loading, thus improving performance. You can also bind nested one-to-one relationships using a colon.

// This uses 1 SQL query to fetch the user, associated city, and associated country.
$users = ORM::factory('user')->with('city')->with('city:country')->find_all();
 
foreach($users as $user) {
  echo $user->city->country->name;
}

You can also set the $load_with property of the ORM model to bind automatically.

foreign_key()

public function foreign_key($table = NULL, $prefix_table = NULL)

Determines the name of a foreign key for a specific table.

Parameters:

  1. string|bool|null Related table name, null or (bool) true
  2. string|null The prefix table name (used for JOINs) or null
// Sets $model->object_name.'_'.$model->primary_key, ie user_id
$join_col = $model->foreign_key();
// Sets $model->table_name.'.'.$model->primary_key, ie users.id
$join_col = $model->foreign_key(TRUE);
// Sets $join_table.'.'.$model->object_name.'_'.$model->primary_key, ie blogs_users.user_id
$join_col = $model->foreign_key(NULL,$join_table);

See also the protected property $foreign_key.

join_table()

public function join_table($table)

This uses alphabetical comparison to choose the name of the join table.

Parameters:

  1. string The name of the table to join with.

This creates either $model→table_name'_'.$table or $table.'_'.$model→table_name

Example: The joining table of users and roles would be roles_users, because “r” comes before “u”. Joining products and categories would result in categories_products, because “c” comes before “p”.

$user = ORM::factory('user');
echo $user->join_table('roles'); // roles_users

The order is standard English order: zoo > zebra > robber > ocean > angel > aardvark

count_all()

Count all results found.

Example:

$db = ORM::factory('article')->where('tags', 'bali');
echo $db->count_all();

count_last_query()

Count how many results found on last query.

Example:

$db = ORM::factory('user')->where('hometown', 'bali');
echo $db->count_last_query();

Properties

ORM has several public object properties which can be used for various purposes. By default, all of these properties are managed by ORM and will change dynamically based on object. They should never be manually set in a model.

loaded

Boolean for seeing whether the current object has been loaded from the database. This can be used to test if an object has been successfully loaded.

$article = ORM::factory('article', 1);
 
if ($article->loaded==TRUE)
{
    echo 'loaded article ', $article->id;
}
else
{
    echo 'no article by that id exists';
}

changed

Array used by ORM to keep track of changes made to columns in an ORM model prior to saving. You can check the status of a specific column by using isset($this→changed['name']).

The changed property is very useful within the context of an overloaded save() method in your ORM Model. Overloading the save() method allows you to perform extra processing, filtering or data integrity checks prior to saving any new/updated data for your ORM Model.

// overload the save method in your ORM Model
 
public function save()
{
    if (isset($this->changed['name']))
    {
        // set the slug when the name changes -- 'my-post-name'
	$this->slug = url::title($this->name);
    }
}

saved

Boolean for checking 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';
}

object_name

The simple name of the object. If my class is named Blog_Post_Model, then blog_post is the object_name.

primary_key

The column name of the primary key. If your primary key is a foreign key, then you specify that as your primary key.

// This example uses field 'usercode' as primary key
class User_Model extends ORM {
 
    protected $primary_key = 'usercode';
 
}

primary_val

A convenience value corresponding to a column in the table. By default it is set to name. It can be used as a more human-friendly identifier for table rows. For instance, if you had a users table, you might set it to username.

class User_Model extends ORM {
 
    protected $primary_val = 'username';
 
}

table_name

The name of the database table that holds the records.

// This example use 'usuarios' table for User_Model
class User_Model extends ORM {
 
    protected $table_name = 'usuarios';
 
}

table_columns

The database table column information that is being used.

class User_Model extends ORM {
 
    protected $table_columns = array('id','username','last_login','anotherfield');
 
}

sorting

An array of sorting parameters that should be applied to queries. By default, results are sorted by id ASC. You can add multiple columns and directions to this property.

class User_Model extends ORM {
 
    protected $sorting = array('last_login' => 'desc', 'username' => 'asc');
 
}

load_with

Allows you to specify which relations should always be joined.

class Blog_Post_Model extends ORM {
 
    protected $load_with = array('user');
 
}

Continue to the next section: Getting Started >>