Model Classes / Code Generator

By orqi

What are model classes? Well a wee reminder, “the Model. This can be a bit tricky to get your head around because most books start talking about business logic and business rules when the Model is essentially the “things in your system” This means for example if your application has users in it, you will have a “users” table in your database and a “User” class that represents one user. You can then use another class (usually a Mapper in MVC) to read and write stuff to the database.”

The Mappers we’ll get on to in a bit. Suffice to say a Model class should be able to report it’s values and sub-objects (via getters) and obviously be able to set it’s values. (Don’t worry about setting sub-objects, the Orqi mapping stuff isn’t that complicated yet).

Another common occurrence in Orqi is that the Model classes basically look like the table in the database that they correspond to.

Model classes are usually very similar in structure and since creating and typing them out can be quite tedious and time consuming, there is a code generator which will create the file for you with the object linking and lazy loading support built-in.

Using the code generator

The model code generator can take two types of field. ‘Normal’ and ‘Object Links’ for want of better names. ‘Normal’ fields correspond to columns in the database table that your object relates to. That is to say if you have an object called User and it has a field called ‘Object Link’ fields correspond to columns in the database that link to other database tables.

OK, go to http://www.orqi.co.uk/model-class-generator.html and you will see a form like this …

I’ve filled the titled in as “BlogComment” and filled the field in as “post, posts_id, name, email, timestamp, approved” hit submit and you should get a Model file that look akin to this …


class BlogComment extends Object
{
	var $id;
	var $post;
	var $posts_id;
	var $name;
	var $email;
	var $timestamp;
	var $approved;

	function BlogComment($id='', $post='', $name='', $email='', $timestamp='', $approved='')
	{
		$this->id = $id;
		$this->post = $post;
		$this->name = $name;
		$this->email = $email;
		$this->timestamp = $timestamp;
		$this->approved = $approved;
	}

	function GetPost()
	{
		if ($this->isGhost()) $this->PopulateMe();
		if (!is_a($this->post, 'Post')) $this->post = new Post($this->posts_id);
		return $this->post;
	}

	function GetName()
	{
		if ($this->isGhost()) $this->PopulateMe();
		return $this->name;
	}

	function GetEmail()
	{
		if ($this->isGhost()) $this->PopulateMe();
		return $this->email;
	}

	function GetTimestamp()
	{
		if ($this->isGhost()) $this->PopulateMe();
		return $this->timestamp;
	}

	function GetApproved()
	{
		if ($this->isGhost()) $this->PopulateMe();
		return $this->approved;
	}

	function SetPost($post='') { $this->post = $post; }
	function SetName($name='') { $this->name = $name; }
	function SetEmail($email='') { $this->email = $email; }
	function SetTimestamp($timestamp='') { $this->timestamp = $timestamp; }
	function SetApproved($approved='') { $this->approved = $approved; }
}

This file is ready to use. Simply put it in your “_classes/_domain” directory and then add it to your index.php file to include it in your project.


$config->LoadFile($config->classes['domain'] . "/BlogComment.php");

Points to Note

Lazy Loading

You might be looking at this file and thinking why do all the getters have the following line of code. Seems a bit long winded. This is just Orqi’s Lazy Loading implementation. Lazy Loading allows you to compose vast graphs of linked classes and objects, with the benefit of only loading from the database that which you use.

if ($this->isGhost()) $this->PopulateMe();

The only drawback is that your objects must always be checking if they are loaded with data or not.

What does this mean for us in terms of code?


// we can do this with lazy loading
echo $blogcomment->GetPost()->GetTimestamp();

// without lazy loading we have to this
$posts_mapper = new Posts();
$post = $posts_mapper->FindByComment($blogcomment);
echo $post->GetTimestamp();

Pretty cool isn’t it! For more information on Lazy Loading: Read the wiki entry on Lazy Loading

Automatic Object Linking

Notice that Post is an object. Since we expect an object when we ask for one, the code generator will naturally put an extra line in the object getters that takes the corresponding database field as an id and instiates an object with it.


function GetPost()
{
	if ($this->isGhost()) $this->PopulateMe();
	if (!is_a($this->post, 'Post')) $this->post = new Post($this->posts_id);
	return $this->post;
}

Database!

We’ll talk about ORM more in the Mapper Classes post. Suffice to say that if I have a class like BlogComment it’s a fairly safe assumption that in my database*, I will have a table more-or-less like this …


CREATE TABLE `blogcomments` (
  `id` int(11) NOT NULL auto_increment,
  `posts_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `timestamp` int(11) NOT NULL,
  `approved` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 ;

* it is of course perfectly possible to call external systems in your mappers, construct you objects and pass them back to your system :D

long post is long o_O – if you made it this far give yourself a pat on the back

Tags: , , ,

Leave a Reply