-
Notifications
You must be signed in to change notification settings - Fork 7
Relationships
If there was an author
table which stored information about blog authors, it could be set up in a similar way:
$authorSource = new \Maphper\DataSource\Database($pdo, 'author', 'id');
$authors = new \Maphper\Maphper($authorSource);
This could be used similarly:
$author = $authors[123];
echo $author->name;
Once both the blogs and authors mappers have been defined, you can create a relationship between them.
This is a one-to-one relationship (one blog has one author) and can be achieved using the addRelation method on the blog mapper:
//Create a one-to-one relationship between blogs and authors (a blog can only have one author)
$relation = new \Maphper\Relation\One($authors, 'authorId', 'id');
$blogs->addRelation('author', $relation);
Using an instance of \Maphper\Relation\One tells Maphper that it's a one-to-one relationship
The first parameter, $authors
tells Maphper that the relationship is to the $authors
mapper (in this case, the author database table, although you can define relationships between different data sources)
authorId
is the field in the blog table that's being joined from
id
is the field in the author table that's being joined to
After the relation is constructed it can be added to the blog mapper using:
$blogs->addRelation('author', $relation);
The first parameter (here: 'author') is the name of the property the related data will be available under. So any object retrieved from the $blogs mapper will now have an 'author' property that contains the author of the blog and can be used like this:
foreach ($blogs as $blog) {
echo $blog->title . '<br />';
echo $blog->author->name . '<br />';
}
Similarly, you can define the inverse relation between authors and blogs. This is a one-to-many relationship because an author can post more than one blog.
//Create a one-to-many relationship between blogs and authors (an author can have multiple blog entries)
//Joining from the 'id' field in the authors mapper to the 'authorId' field in the blogs mapper
$relation = new \Maphper\Relation\Many($blogs, 'id', 'authorId');
$authors->addRelation('blogs', $relation);
This is creating a One:Many relationship between the $authors
and $blogs
mappers using the id
field in the $authors
mapper to the authorId
field in the $blogs
mapper and making a blogs
property available for any object returned by the $authors
mapper.
//Count all the blogs by the author with id 4
$authors[4]->name . ' has posted ' . count($authors[4]->blogs) . ' blogs:<br />';
//Loop through all the blogs created by the author with id 4
foreach ($authors[4]->blogs as $blog) {
echo $blog->title . '<br />';
}
Once you have created your mappers and defined the relationships between them, you can write data using the relationship. This will automatically set any related fileds behind the scenes.
$authors = new \Maphper\Maphper(new \Maphper\DataSource\Database($pdo, 'author'));
$blogs = new \Maphper\Maphper(new \Maphper\DataSource\Database($pdo, 'blog', 'id'));
$blogs->addRelation('author', new \Maphper\Relation\One($authors, 'authorId', 'id'));
$blog = new stdClass;
$blog->title = 'My First Blog';
$blog->date = new \DateTime();
$blog->author = new stdClass;
$blog->author->name = 'Tom Butler';
$blogs[] = $blog;
This will save both the $blog
object into the blog
table and the $author
object into the author
table as well as setting the blog record's authorId column to the id that was generated.
You can also do the same with one-to-many relationships:
$authors = new \Maphper\Maphper(new \Maphper\DataSource\Database($pdo, 'author'));
$blogs = new \Maphper\Maphper(new \Maphper\DataSource\Database($pdo, 'blog', 'id'))
$authors->addRelation('blogs', new \Maphper\Relation\Many($blogs, 'id', 'authorId'));
//Find the author with id 4
$author = $authors[4];
$blog = new stdClass;
$blog->title = 'My New Blog';
$blog->date = new \DateTime();
//Add the blog to the author. This will save to the database at the this point, you do not need to explicitly
//Save the $author object after adding a blog to it.
$author->blogs[] = $blog;