Reverse detail from Kakelbont MS 1, a fifteenth-century French Psalter. This image is in the public domain. Daniel Paul O'Donnell

Forward to Navigation

Understanding Relation Models in Yii

Posted: Feb 24, 2012 13:02;
Last Modified: May 23, 2012 18:05
Keywords:

---

The core of any database driven website is its ability to handle table relations (if that sentence didn’t mean anything to you, you should first do some reading about relational databases, database design, and normalising data: an introduction aimed at textual editors can be found in my article “What digital editors can learn from
print editorial practice.” Literary and Linguistic Computing 24 (2009): 113-125)

One of the really useful things about the Yii MVC framework is the extent to which it allows you to systematise and automate the process of establishing these relations.

The relations() method

The most important part of this system is in the Yii model classes. When you first scaffold a new website in Yii (see the Yii website for the extremely easy to implement details of how this is done), the gii utility will build a series of standard model classes, each of which corresponds to a table in your database. A core method, included in every one of these models by default, is relations() (note: the following is how an empty relation method looks):

/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
                );
        }

To indicate that the table represented by this model is related to other tables in your database, you construct a number of relation key => value pairs using a series of pre-defined terms (see these sections of the Yii Blog Tutorial and of the Yii documentation for details).

You can do this quite easily by hand. But if your database is designed using an engine that supports explicit information about relations (such as MySQL’s InnoDB engine [but not the default MYISAM]), Yii’s scaffolding utility gii will do much of the work in populating this method automatically.

Here’s an example of a relationset, built for a table in one of my databases (the model is called Journal and describes a table containing information about journals in a publishing workflow):

public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'articles' => array(self::HAS_MANY, 'Article', 'journal_id'),
			'editorialInstances' => array(self::HAS_MANY, 'EditorialInstance', 'journal_id'),
		);
}

In human terms, this is what the method is indicating:

  1. the journal table is directly related to two other tables in my database: article and editorialInstance (in my database, tables are named using camelCase starting with an initial lowercase letter; Yii’s naming convention is that Model Classes [i.e. the models that describe tables] begin with a capital letter: so Article is the model for the database table article).
  2. the relationship between journal and these two tables is
    1. parent to child (journal HAS article and editorialInstance)
    2. one to many (journal HASMANY_ article and editorialInstance
  3. the key names in the relations array article*s* and editorialInstance*s* are themselves arrays of all the possible values in these child tables
  4. both the child tables contain journal_id as a foreign key (FK)

How the relations() method makes your life easier

The great thing about this relations() method is that it turns relations into attributes of the model itself. That is to say, attributes of the related tables can be access directly from the model in which they are declared.

This is easiest to see with the BELONGS_TO (many-to-one child-to-parent) relation, which isn’t instanced above. Here’s an example from the EditorialInstance model, however: i.e. one of the children of Journal in my database:

public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'journal' => array(self::BELONGS_TO, 'Journal', 'journal_id'),
			'person' => array(self::BELONGS_TO, 'Person', 'person_id'),
		);

In this case, you can see tat EditorialInstance is the child of two databases (that is to say it BELONGS_TO them).

When a BELONGS_TO relationship is declared in a model, the attributes of the parent table are treated exactly like the attributes of the child table in the declaring model. I.e. let’s say the editorialInstance table has an attribute called type and we are referencing it like this in an editorialInstanceView: $data->type; we can also access all the attributes of the parent tables as well through this same model using language: so the lastName attribute on person would be referenced in this same context $data->person->lastName

Relational queries

----  

Commenting is closed for this article.

Back to content

Search my site

Sections

Current teaching

Recent changes to this site

Tags

anglo-saxon studies, caedmon, citation practice, composition, computers, digital humanities, digital pedagogy, grammar, history, moodle, old english, pedagogy, research, students, study tips, teaching, tips, tutorials, unessay, universities

See all...

Follow me on Twitter