Showing posts with label single table. Show all posts
Showing posts with label single table. Show all posts

Friday, January 8, 2016

Doctrine Single Table Inheritance

I have a request to develop 3 forms to collect information from users. They share some  of the information like: name, address, dateamount and some fields are different, each form will have some attachments (3 or 2) which represent different types of documents. More than that on the 'amount ' field there are different validations to make, depending on which form is applied.

How should I implement this? After some research the Doctrine Single Table Inheritance seems to be the answer:

Official documentation: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html
Useful blog: https://blog.liip.ch/archive/2012/03/27/table-inheritance-with-doctrine.html

Because the objects (corresponding to the forms) to be saved in the database have a lot in common  they can all be kept in just one table. The table needs to allow NULL for the fields which are not common for all forms.

In Symfony I will create a base entity class which will be extended by child entities (one child for each form). The base entity can be "abstract' as it is not supposed to be directly used (the child entity classes  will be used just as regular entities ).
Because I want to have different validation on the 'amount' field (and I want to keep them in  entity) I will move the 'amount' from the base class to child classes.
Also in the table there will be a column which will keep the type of the record (object typeA from formA, object typeB from formB, etc ). The equivalent of this column in Doctrine language is DiscriminatorColumn.

        @ORM\DiscriminatorColumn: indicates which column will be used as discriminator (i.e. to store the type of item). You don’t have to define this column in the entity, it will be automagically created by Doctrine.

Exaple:

Base entity class:


<?php

namespace Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Base entity class
 *
 * @ORM\Table(name="table")
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="refund_type", type="string")
 * @ORM\DiscriminatorMap( {"typeA_in_database" = "ChildEntityA", "
typeB_in_database" = "ChildEntityB" } )
 */
abstract class Base
{

 --------------------------------------
---------------------------------------
Child entity class

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use DDRCBundle\Validator\FilesTotalSize;

/**
 * @ORM\Entity
 * Child
 *
 */
class Child extends Base