Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with multiple relationship in one field on Doctrine 2

I'm having a little problem with a possible multiple relationship in one field in Doctrine 2. For example, i have an Article entity with one field called author. This field is a ManyToOne to the User entity. However, this field can also relate to the Group entity. So, how the hell can i create such schema?

I have considered creating a new entity, called ArticleAuthor which has two fields: user and group, and depending on form input, i populate one of the fields. This way, this table ArticleAuthor holds it's own id and the proper relationship to the correct table. Is this a correct approach?

like image 698
vinnylinux Avatar asked Oct 19 '12 15:10

vinnylinux


1 Answers

This is what's referred to as a polymorphic association. Doctrine is able to handle these using Inheritance Mapping

So you'd define your base entity, such as Author, and then you'd have a GroupAuthor and a UserAuthor which both extend this. These both need to be configured as mapped classes on the base Author entity. It's up to you whether you opt for single table or class table inheritance; the end result would be the same.

The last thing to do is to associate the UserAuthor entity to your User entity, and your GroupAuthor to your Group entity.

Then you'd be able to use it somewhat like this:

$author = $article->getAuthor();
if ($author instanceof UserAuthor) {
    $user = $author->getUser();
} elseif ($author instanceof GroupAuthor) {
    $group = $author->getGroup();
    $users = $group->getUsers(); // Not sure if you'd need this?
}

Edit: Example mapping

The 'parent' entity, Author.php

/**
 * @ORM\Entity
 * @ORM\Table(name="authors")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap( {"user" = "UserAuthor", "group" = "GroupAuthor"} )
 */
class Author
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /* any other shared fields... */
}

Mapped entity, UserAuthor.php

/**
 * @ORM\Entity
 * @ORM\Table(name="user_authors")
 */
class UserAuthor extends Author
{
    /* All columns unique to the UserAuthor entity... */
}

etc

like image 81
RobMasters Avatar answered Oct 07 '22 19:10

RobMasters