One To Many Relationship with Zend Framework

| 3 Comments

The previous article on this blog was about the dynamical select list with the Zend Framework and some introductory material (mainly tutorials).

Two weeks later I am still working with the Zend Framework and now the tasks getting a little bit advanced. So I had again to crawl the web a little bit to find a solution for my problem. The problem was to look up related values from a fetched row and display the complete results.

Normally I have done this in PHP with a Join in the Where condition(s) and could then, since I most of the time look that my column names are unique, access the values directly via the mysqli-object. You could also do the Join statements with the standard Select object in the Zend Framework, but I was not sure how then the result array should be accessed or if it would work the same way as in standard PHP. So I had to have a look into the documentation. But I have to warn you, the introductory example is so scattered in the whole documentation that you need quite a little time to have the complete example together. So I had another look into Zend Framework in Action from Rob Allen and Nick Lo (2007), where the example was nicely illustrated with an ERM.

As soon as I had gathered all informations and get the principle of how the relationship is represented in the framework, I could implement my solution into my existing application.


A few remarks to the "landscape" of my application before I start to explain the logic of the relationship and throw a little bit of code on you:
I will keep it simple here and just mention the necessary tables, which are in fact two here. One is a representation of an artist respectively of the information about an artist or a band. Among other, I want to display from where the artist come or to be more precisely, what is the home country of a band. Since data about nation can easily be used in different situations, I have an own table for them (I got the list from here).

Preparation of application
The next step is to prepare the application respectively the model to handle the relationship we want to have. Therefore Zend_Db_Table offers some configuration parameters. You find them all in the documentation.

First we need to declare on the model from which we want to reference to another table. We do this with the code shown below:

class Artists extends Zend_Db_Table
{
protected $_name = "artists";

protected $_dependentTables = array('Nations');
}

That should be enough. If you want you can also declare another primary key for the table and so on. But I am sure you know that already. Be careful and state here the name of the model class and not the one of the table identifier from MySQL.

The next step is in bringing some light in this dependency. For now we have only declared, that the table artists is related to the Nations model. We will do this with a configuration option in the Nations model:

class Nations extends Zend_Db_Table
{
protected $_name = 'nations';

protected $_referenceMap = array(
		'Artists' => array(
			'columns'		=> array('nation_id'),
			'refTableClass'	=> 'Artists',
			'refColumns'	=> array('artist_nation')
			)
		);
}

We have here the variable $_referenceMap, which holds an array and thus can hold more than one reference. For a keyword, here 'Artists', we provide the dependencies. Which column in Nations is concerned, which are the reference Columns (refColums) and which is the reference table class.
With this two steps we are prepared for executing our query.

Executing the query
This is now the easier part, but there is another little tweak we need to succeed. The code I used looks like the following:

// code above left out
$artist = new Artists;
$curArtist = $artist->fetchRow('artist_id = '.$id);
$this->view->artist = $curArtist;
$this->view->nation = $curArtist->findDependentRowset('Nations')->current();
// code below left out

First we instantiate the Artists model. Then we search for a certain id (at least this was what I did). I have saved the result set for the current artist (with the id) in a separate variable, which might be not necessary. For the output I assign the result set to the view parameter I would like to use on the next line.
Then we come to the dependent row, which we directly assign to the parameter for the view. We call the function findDependentRowset(), with the parameter we have set in the model (see first code example). And finally, we set the results gained from this "query" to the current returned rowset. We need to do this, because if we do not, we could not access the rowset in the view.

So that is all about querying dependent tables with the Zend Framework, or to be more precisely: The query of a One-To-Many relationship.

3 Comments

Hi!
thanks for the tutorial.

How can I create a grid within all the main fields and the nation foreign field too?

thanks

Hi that is a genuinely interesting view, It does give one food for thought, I am very delighted I stumbled on your blog, i was using Stumbleupon at the time, in any case i don’t want to ramble on too much, but i would like to say that I will be back when I have a little time to read your blog more thoroughly, Once again thanks a lot for the blog post and please do keep up the right work,

Leave a comment