Skip to content
This repository was archived by the owner on Jul 11, 2024. It is now read-only.

Relationships

dominis edited this page May 21, 2011 · 3 revisions

Relationships

This tutorial guides you through the modelling of relationships in Morph

Has vs Compose

Morph and MongoDB below it allow you as a developer to model related objects in 2 different ways

  • Compose - Embedded sub-objects
  • Has - separate related objects

The decision as to which type of relationship you wish to model is entirely up to you.

Embedded sub-objects are fast, they are retrieved as part of the parent object itself. However, they cannot be used independently or re-used by other objects.

Has objects are stored in a separate collection and can therefore be queried, re-used and tried entirely separately. The disadvantage is that the are not loaded automatically when you retrieve the parent object. The are lazy loaded the first time they are accessed by Morph. Morph takes care of the loading for you but it does result in 2 separate calls the MongoDB.

Multiplicity

For each type of related object (Compose & Has) there are 2 Morph property objects. One for singular relationships and one for multiple related objects.

Lets start with the singular relationships are these are the simplest.

Compose/Has One

For example:

class Book extends \morph\Object
{
    public function __construct($id = null)
    {
        parent::__construct($id);
        $this->addProperty(new \morph\property\String('title'))
             ->addProperty(new \morph\property\ComposeOne('author', 'Author'));
    }
}

The class defined above represents a book and holds 2 storable properties:

  • title - A string to hold the title of the book
  • author - A ComposeOne related object of type Author called author

The author field can be treated like a normal public property holding an Author object. For example an Author Compose a property name which can be accesses as normal

echo "Author is: " . $aBook->author->name;
$aBook->author->name = 'Moose';
$aBook->save();

From the above example you can see that you cat retrieve and set the author->name field like any normal property.

Equally, you can set the whole author object directly:

$author = new Author();
$author->name = 'Moose';

$aBook->author = $author;
$aBook->save();

Note that the author sub-object is automatically saved when $aBook->save() is called.

The HasOne property type acts in exactly the same way. The only difference is that the sub-object will be saved independently of the parent object in it's own collection and will therefore get it's own ObjectId.

Has/Compose Many

The ComposeMany and HasMany work in a very similar way except that the property defined at ComposeMany or CompoeseMany act like arrays:

class Book extends \morph\Object
{

    public function __construct($id = null)
    {
        parent::__construct($id);
        $this->addProperty(new \morph\property\String('title'))
             ->addProperty(new \morph\property\ComposeMany('authors', 'Author'));
    }

}

You can then treat the author property just like an array:

//accessing
foreach ($aBook->authors as $author) {
   echo "Author: " . $author->name . "\n";
}

//adding

$author1 = new Author();
$author1->name = 'Moose';

$author2 = new Author();
$author2->name = 'Shark';

$aBook->authors[] = $author1;
$aBook->authors[] = $author2;
$aBook->save();

The HasMany property works in exactly the same way. Again, the only exception is on the backend and how the author is stored in MongoDB. ComposeMany relationships are stored as an array of sub-objects within the parent object itself. HasMany relationships are stored as individual objects within their own collection and an array of references stored in the parent object.

HasMany related objects are lazy loaded when they are first accessed. ComposeMany are pulled back from MongoDB at the same time as the parent object are they are part of it.

Clone this wiki locally