This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/includes/kohana/modules/userguide/guide/nl/tutorials.orm.md
2011-05-03 09:49:01 +10:00

12 KiB

ORM

Kohana 3.0 bevat een krachtige ORM-module die het "active record"-patroon gebruikt en database introspectie gebruikt om kolominformatie te bepalen van een model.

De ORM-module is opgenomen in de Kohana 3.0 installatie maar moet worden ingeschakeld vooraleer je het kunt gebruiken. In je application/bootstrap.php bestand moet je de oproen naar [Kohana::modules] aanpassen en de ORM-module insluiten:

Kohana::modules(array(
	...
	'orm' => MODPATH.'orm',
	...
));

Configuratie

ORM vergt weinig configuratie om aan de slag te kunnen. Breid uw model classes uit met ORM om de module te kunnen gebruiken:

class Model_User extends ORM
{
	...
}

In het voorbeeld hierboven zal het model zoeken naar een tabel users in de standaard database.

Model Configuratie Properties

De volgende eigenschappen worden gebruikt om ieder model te configureren:

Type Eigenschap Omschrijving Standaard waarde
string _table_name Tabelnaam om te gebruiken singular model name
string _db Naam van de database om te gebruiken default
string _primary_key Kolom die dient als primary key id
string _primary_val Kolom die dient als primary value name
bool _table_names_plural Zijn de tabelnamen meervoudig? TRUE
array _sorting Array met kolom => volgorde primary key => ASC
string _foreign_key_suffix Achtervoegsel voor foreign keys _id

Het gebruik van ORM

Een Record inladen

Om een instantie van een model aan te maken, kan je de [ORM::factory] methode of [ORM::__construct] gebruiken:

$user = ORM::factory('user');
// of
$user = new Model_User();

De constructor en factory methodes accepteren ook een primary key waarde om het gegeven model's data in te laden:

// Laad gebruiker met ID 5
$user = ORM::factory('user', 5);

// Kijk of de gebruiker succesvol werd ingeladen
if ($user->loaded()) { ... }

Je kan optioneel een array met keys => value paren meegeven om een data object in te laden die voldoet aan de gegeven criteria:

// Laad een gebruiker met email joe@example.com
$user = ORM::factory('user', array('email' => 'joe@example.com'));

Zoeken naar één of meerdere records

ORM ondersteunt de meeste krachtige [Database] methoden voor het doorzoeken van gegevens van uw model. Zie de _db_methods eigenschap voor een volledige lijst van ondersteunde methode oproepen. Records worden opgehaald met behulp van de [ORM::find] en [ORM::find_all] functies.

// Dit zal de eerste actieve gebruiker nemen met de naam Bob
$user = ORM::factory('user')
	->where('active', '=', TRUE)
	->where('name', '=', 'Bob')
	->find();

// Dit zal alle gebruikers nemen met de naam Bob
$users = ORM::factory('user')
	->where('name', '=', 'Bob')
	->find_all();

Wanneer je een lijst van modellen ontvangt met behulp van [ORM::find_all], kan je deze doorlopen zoals je doet met database resultaten:

foreach ($users as $user)
{
	...
}

Een zeer handige functie van ORM is de [ORM::as_array] methode die het record zal teruggeven als een array. Indien je dit gebruikt met [ORM::find_all], zal een array van alle records worden teruggegeven. Een goed voorbeeld van wanneer dit nuttig is, is voor select in het HTML formulier:

// Toon een dropdown/select met daarin alle gebruikersnamen (id als value van de options)
echo Form::select('user', ORM::factory('user')->find_all()->as_array('id', 'username'));

Het aantal records tellen

Gebruik [ORM::count_all] om het aantal records terug te geven voor een bepaalde query.

// Aantal actieve gebruikers
$count = ORM::factory('user')->where('active', '=', TRUE)->count_all();

Als je het totaal aantal gebruikers wilt tellen voor een bepaalde query, terwijl je enkel een bepaalde set van deze gebruikers wilt tonen, gebruik dan de [ORM::reset] methode met FALSE vooraleer je count_all gebruikt:

$user = ORM::factory('user');

// Totaal aantal gebruikers (reset FALSE zorgt ervoor dat het query object dat het query object niet geleegd wordt)
$count = $user->where('active', '=', TRUE)->reset(FALSE)->count_all();

// Geef enkel de eerste 10 resultaten terug van deze resultaten
$users = $user->limit(10)->find_all();

Properties van een model aanspreken

Alle model properties zijn toegankelijk via de __get en __set magic methodes.

$user = ORM::factory('user', 5);

// Geef de gebruikersnaam terug
echo $user->name;

// Verander de gebruiker zijn naam
$user->name = 'Bob';

Voor het opslaan van gegevens/properties die niet bestaan in de tabel van het model, kan je gebruik maken van het _ignored_columns data member. De gegevens zullen worden opgeslagen in het interne _object member, maar zal worden genegeerd op database-niveau.

class Model_User extends ORM
{
	...
	protected $_ignored_columns = array('field1', 'field2', …);
	...
}

Meerdere key => value paren kunnen worden ingesteld door gebruik te maken van de [ORM::values] methode.

$user->values(array('username' => 'Joe', 'password' => 'bob'));

Aanmaken en opslaan van records

De methode [ORM::save] wordt gebruikt om zowel nieuwe records aan te maken als het upaten van bestaande.

// Nieuw record aanmaken
$user = ORM::factory('user');
$user->name = 'Nieuwe gebruiker';
$user->save();

// Aanpassen van een bestaand record
$user = ORM::factory('user', 5);
$user->name = 'Gebruiker 2';
$user->save();

// Controleer of het record opgeslagen is
if ($user->saved()) { ... }

Je kan meerdere records tegelijk veranderen met de [ORM::save_all] methode:

$user = ORM::factory('user');
$user->name = 'Bob';

// Verander bij alle actieve gebruikers de naam naar 'Bob'
$user->where('active', '=', TRUE)->save_all();

Gebruik Updated en Created kolommen

De _updated_column en _created_column members staan ter beschikking om automatisch aangepast te worden wanneer een model wordt gecreëerd of aangepast. Ze worden standaard niet gebruikt. Om ze te gebruiken:

// date_created is de kolom die wordt gebruikt om de aanmaak datum op te slaan. Gebruik format => TRUE om een timestamp op te slaan
protected $_created_column = array('date_created', 'format' => TRUE);

// date_modified is de kolom die wordt gebruikt om de datum op te slaan wanneer het item is aangepast. In dit geval wordt een string gebruikt om een date() formaat te specificeren
protected $_updated_column = array('date_modified', 'format' => 'm/d/Y');

Verwijderen van records

Records worden verwijderd met [ORM::delete] en [ORM::delete_all]. Deze methoden werken op dezelfde manier als het opslaan van records zoals hierboven beschreven, met de uitzondering dat [ORM::delete] nog een optionele parameter heeft, het id van het record om te verwijderen. Anders wordt het huidig ingeladen record verwijderd.

Relaties

ORM ondersteunt zeer goed relateies. Ruby heeft een goede tutorial omtrent relaties.

Belongs-To en Has-Many

We gaan er van uit dat we werken met een school dat veel (has many) studenten heeft. Iedere student kan enkel maar tot één school behoren (belong to). Dan zullen de relaties als volgt gedefinieerd worden:

// In het model "school"
protected $_has_many = array('students' => array());

// In het model "student"
protected $_belongs_to = array('school' => array());

Om een student zijn school te verkrijgen gebruik je:

$school = $student->school;

Om een school zijn studenten te verkrijgen gebruik je:

// Merk op dat find_all is vereist na "students"
$students = $school->students->find_all();

// Om resultaten te "filteren":
$students = $school->students->where('active', '=', TRUE)->find_all();

Standaard zal ORM willen zoeken naar een school_id model in de studenten tabel. Dit kan worden overschreven door gebruik te maken van het foreign_key attribuut:

protected $_belongs_to = array('school' => array('foreign_key' => 'schoolID'));

De foreign key moet overschreven worden in zowel het student als school model.

Has-One

Has-One is een speciale versie van Has-Many, het enige verschil is dat er maar één enkel record is. In het bovenstaande voorbeeld zou iedere school maar één student hebben (al is dat wel een slecht voorbeeld).

// In het model "school"
protected $_has_one = array('student' => array());

Je moet niet zoals bij Belongs-To de find methode gebruiken wanneer je verwijst naar een het Has-One gerelateerd object, dit gebeurt automatisch.

Has-Many "Through"

De Has-Many "through" relatie (ook bekend als Has-And-Belongs-To-Many) wordt gebruikt in het geval dat één object gerelateerd is met meerdere objecten van verschillende types en omgekeerd. Bijvoorbeeld, een student kan verschillende klassen volgen en een klass kan verschillende studenten hebben. In dit geval wordt een derde tabel gebruikt en een model die dienst doet als pivot. In dit geval noemen we het pivot object/model enrollment (=inschrijving).

// In het model "student"
protected $_has_many = array('classes' => array('through' => 'enrollment'));

// In het model "class"
protected $_has_many = array('students' => array('through' => 'enrollment'));

De inschrijvingstabel (enrollment) moet twee foreign keys hebben, een voor class_id en de andere voor student_id. Deze kunnen worden overschreven door foreign_key en far_key te gebruiken bij het definiëren van de relatie. Bijvoorbeeld:

// In het model "student" (de foreign key verwijst naar dit model [student], terwijl de far key verwijst naar het andere model [class])
protected $_has_many = array('classes' => array('through' => 'enrollment', 'foreign_key' => 'studentID', 'far_key' => 'classID'));

// In het model "class"
protected $_has_many = array('students' => array('through' => 'enrollment', 'foreign_key' => 'classID', 'far_key' => 'studentID'));

Het inschrijvings model (enrollment) zal als volgt gedefinieerd worden:

// Het model "enrollment" hoort bij zowel "student" als "class"
protected $_belongs_to = array('student' => array(), 'class' => array());

Om de gerelateerde objecten te bereiken, gebruik je:

// Om de klassen van een student te verkrijgen
$student->classes->find_all();

// Om studenten te verkrijven vanuit de klas
$class->students->find_all();

Validatie

ORM werkt nauw samen met de [Validate] library. ORM biedt de volgende members aan voor validatie

  • _rules
  • _callbacks
  • _filters
  • _labels

_rules

protected $_rules = array
(
	'username' => array('not_empty' => array()),
	'email'    => array('not_empty' => array(), 'email' => array()),
);

username zal gecontroleerd worden om zeker niet leeg te zijn. email zal ook gecontroleerd worden om te verzekeren dat het een geldig emailadres is. De lege arrays die als values worden meegestuurd, kunnen worden gebruikt om optionele parameters mee te geven aan deze functie aanroepen.

_callbacks

protected $_callbacks = array
(
	'username' => array('username_unique'),
);

username zal worden meegestuurd naar een callback methode username_unique. Als de methode bestaat in het huidige model, zal het worden gebruikt, anders zal een globale functie worden opgeroepen. Hier is een voorbeeld van z'n methode:

public function username_unique(Validate $data, $field)
{
	// Logica om te controleren of de gebruikersnaam uniek is
	...
}

_filters

protected $_filters = array
(
	TRUE       => array('trim' => array()),
	'username' => array('stripslashes' => array()),
);

TRUE slaat erop dat de trim filter wordt gebruikt voor alle velden. username zal ook gefilterd worden door stripslashes vooraleer het gevalideerd wordt. De lege arrays die als values worden meegestuurd, kunnen worden gebruikt om optionele parameters mee te geven aan deze filter-functie aanroepen.

Controleren of een Object Valid is

Gebruik [ORM::check] om te kijken of het object momenteel valid is.

// Een object zijn values instellen en dan controleren of het valid is
if ($user->values($_POST)->check())
{
	$user->save();
}

Je kan de validate() methode gebruiken om een model zijn validatie object aan te roepen.

// Een optionele filter manueel toevoegen
$user->validate()->filter('username', 'trim');