automatix
automatix

Reputation: 14522

Does Doctrine provide support for polymorphic relationship?

There is a type/table EveryoneNeedsMe/everyone_needs_me (in my concrete case it's Message/messages). And actually there are multiple types/tables, that need it, e.g. Foo/foo or Bar/bar. I'd like to use the polymorphic relationship pattern (or polymorphic associations):

objects_to_enm
- id
- everyone_needs_me_id
- object_type // e.g. "foo" or "bar"
- object_id // the foo's or bar's IDs
// The combination of object_type and object_id has to be UNIQUE.

everyone-needs-me

Some ORMs (e.g. Eloquent, s. docu) support the polymorphic relationship pattern. Does Doctrine 2 support it as well?

If yes: How to use it in Doctrine 2? If no: How to handle this case with Doctrine?

Upvotes: 1

Views: 1382

Answers (1)

ilicmsreten
ilicmsreten

Reputation: 468

Yes, Doctrine support multiple Inheritance mapping. But if I clearly understand you want to each entity have own table in DB.

So you can do something like this, define parent class

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"foo"="Foo","bar"="Bar"})
 */
abstract class ParentClass
{

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\Message")
     */
    protected $message;

   //getter,setter,other code
}

Your class Foo and Bar will extend ParentClass e.g.

/**
 * @ORM\Entity()
 */
class Foo extends ParentClass
{
    /**
     * @ORM\Column(type="string")
     */
    protected $body;
}

So after that you can do

$foo = new Foo();
$foo->setId(1);
$foo->setBody('Some Text');
$foo->setMessage($messageObject);
$entityManager->persist($foo);
$entityManager->flush();

After this in parentclass table you will get something like

| id         | message_id | discr      |
|------------|------------|------------|
| 1          |        1*  |     foo     

and then in you code you can

$fooObject = $entityManager->getRepository(ParentClass::class)->find(1);

Doctrine will automatically return object that are persisted with that id in this example Foo object.

Full documentation, an other way how to deal with inheritance mapping, like "SINGLE_TABLE" you can check at doctrine-project.

Upvotes: 1

Related Questions