LavaSlider
LavaSlider

Reputation: 2504

Symfony/Doctrine Shared Entity

I would like to create a Note entity in my Symfony project that can be used with multiple other entities. For example, it could be used to leave a comment about a product or a comment about a supplier or a comment about an order. These will be much like the User Contributed Notes in the PHP manual.

All my entities have an integer ID and so I thought the best way to implement this would be to have ownerId and ownerType fields on the note. The ownerId would be set to the product's ID, the supplier's ID or the order's ID. The ownerType would be set to the entity name.

In any entity that I wanted to have notes attached to (e.g., product, supplier, order, etc.) I would add:

/**
 * @ORM\OneToMany( targetEntity="Note", mappedBy="ownerId" )
 */
private $notes;

public function addNote( $n ) {
    if( !$this->notes->contains( $n ) ) {
        $this->notes[] = $n;
        $n->setProduct( $this );
    }
}

In the note I would have have:

public function setOwner( $o ) {
    $this->ownerId = $o->getId();
    $this->ownerType = get_class( $o );
}
public function setProduct( $p ) {
    $this->setOwner( $p );
}
public function setSupplier( $s ) {
    $this->setOwner( $s );
}
public function setOrder( $o ) {
    $this->setOwner( $o );
}

It creates problems because there is no owning side field or the owning side field is not an association or, if I create one, its target entity is wrong, etc.

Is there any way to implement this structure using Symfony and Doctrine? I really don't want to have to have ProductNote, SupplierNote, OrderNote, etc., etc., etc., tables and all the duplicated code.

Upvotes: 2

Views: 645

Answers (1)

M. Kebza
M. Kebza

Reputation: 1518

What you looking for is Doctrine inheritance. With this you will create Note model as abstract and then create ProductNote, SupplierNote and etc just like simple entities (will by just class and @Entity annotation).

For you use case (because you have same structure for everything) I would go for single table inheritance which is using one table and will not have performance impact.

Then in your child classes (for example ProductNote) you will have just setOwner which will accept concrete object and you can map one field for all child entities.

Upvotes: 2

Related Questions