Kohana PHP with ORM and Formo – db made easy!

Posted on September 17, 2009

1


After some days prototyping with Kohana, I start to realize the strength and beauty!

One of the every-day needs in my world is to coordinate different database tables to get things to work. Most of the time this is done by hand, using PhpMyAdmin. For basic stuff, this works fine, but very often there’s the bad feeling of should-have-a-real-admin-interface-for-this…

No bad feelings no more! ๐Ÿ™‚ The combination of Kohana’s Object Relational Mapping library (ORM) and the Formo module makes it super-easy to create a table-admin-interface, including related tables. No SQL at all, no defining form layouts at all! (Ok, there can be a need for some validation information, some styling etc.)

Here’s an example, based on two tables, schools and students:

schools: <- Note: Table name in plural
id:int autoincrement
name:varchar

students:  <- Note: Table name in plural
id:int autoincrement
school_id:int   <- Note! Referred table as singular + "_id"
name:varchar

Two models for those tables:

// models/student.php
class Student_Model extends ORM {
protected $belongs_to = array("school");
// Defines the connection to school - "each student belonst to a school"
}
// models/school.php
class School_Model extends ORM {
protected $has_many = array("students");
// Defines the connection to students - "each school has many students"
}

So for the controller. Here’s the real beauty: In the listAll action below the schools are fetched, and ORM handles automatically the relationship and fetches all connected students as well!

// controllers/controllername.php
public function listAll() {
$schoolModel = new School_Model();
$schools = $schoolModel->find_all();
foreach ($schools as $school) {
echo "<br/><b>$school->name - ".html::anchor("controllername/school/{$school->id}", "edit")."</b>";
foreach ($school->students as $student) {
echo "<br/>- $student->name - ".html::anchor("controllername/student/{$student->id}", "edit");
}
}
}

The actions below handle both creation and editing of posts. The super-handy Formo library maps out a complete form – including dropselect for selecting a school for the students! ๐Ÿ™‚ Kind of magic!

// controllers/ormtest.php
public function school($id = false) {
$school = new School_Model($id);
$form = Formo::factory()->orm($school)->add("Submit");
echo $form;
if ($form->validate()) {
$form->save();
}
}

public function student($id = false) {
$student = new Student_Model($id);
$form = Formo::factory()
  		->orm($student)
  		->add("Submit");
if ($form->validate()) $form->save();
echo $form;
}

The only “tricky” part is that you have to get the table names and references to them right according to the ORM naming conventions. Here’s a short summary:

  • Table names should be plural
    (“schools”, “students” – this makes sense because the table is a list with many items)
  • Referring field names should be singular plus “_id”
    (“school_id” – logically because a single student belongs to one single school)
  • Model names should be singular.
    (The model file for a student is named “student.php”, and the class is named “class Student_Model extends ORM”. A model most of the time represent one single item: one student or one school. The exception is when we want a listing of all items in the table. Have a look at the listAll code above.)

The models need to include information about the relations.

  • The student belongs to one of many schools, therefore we use
    protected $belongs_to = array(‘schools’);
    with plural in “schools”
  • The school has one or many students, thus
    protected $has_many = array(‘students’);

Note that this relates to a one-to-many relationship.

Advertisements
Tagged: , , ,
Posted in: Database, Kohana PHP, PHP