Search code examples
symfonyinheritancedoctrinediscriminatorsymfony3.x

Inheritence in Symfony3 with discriminator


I want to create this tables description in symfony:

GeneralAssignment:

  • id (int)
  • name (text)
  • course (Course)
  • type (1|2)
  • assignment (Assignment1 if type==1|Assignment2 if type==2)

Course:

  • id (int)
  • name (text)

Assignment1:

  • id (int)
  • general_assignment (GeneralAssignment)

Assignment2:

  • id (int)
  • general_assignment (GeneralAssignment)

So the best solution is to use this relation schema:

[Simple relation ManyToOne] (Course) : Course.id <------> GeneralAssignment.course (GeneralAssignment)

And

[JOINED Ineritence type] (GeneralAssignment) : GeneralAssignment.type [1=Assignment1|2=Assignment2]

So I will get this class model (sorry for this bad photo):

class model

Problem

I used to create this model because I want to firstly, create the Course, then create the GeneralAssignment using the course id and finally, create the specific assignment using the general assignment's id

The problem is, I can't create a relation doctrine relation between Assignment1 and GeneralAssignment using Assignment1.general_assignment : "Cannot instantiate abstract class AssignmentGeneral". (the same thing between Assignment2 and AssignmentGeneral).

I need the Assignment1.assignment_general attribute because i'm going to use Assignment1 and Assignment2 classes later and if I can't know the general_assignment id, I can't even know the assignment general informations because of the inheritence from AssignmentGeneral to the specific Assignment classes (Assignment1, Assignment2)

The AssignmentGeneral is an abstract class because of the DiscriminatorMap requires that the class should be abstract.

So what to should I do ?

I can't set the AssignmentGeneral from "abstract class" to "class" and I can't create a relation between Assignment1 (or Assignment2) and GeneralAssignment in Assignment1

PS : These class names are not the real ones, but they are similiar to my real problem. Just to get it simple, I exposed this simple problem.

Thank you very much for each answer

Best regards

[Edit] I'm adding the AssignmentGeneral declaration

/**
 *
 * @ORM\Table(name="assignment_general")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="integer")
 * @ORM\MappedSuperclass
 * @ORM\DiscriminatorMap({
       1 = "Assignment1",
 *     2 = "Assignment2"
 * })
 */
abstract class StatisticsGeneralAbstract
{
 //...
}

And also:

/**
 *
 * @ORM\Table(name="assignment1")
 * 
 */
class Assignment1 extends AssignmentGeneral
{
//...
}

/**
 *
 * @ORM\Table(name="assignment2")
 * 
 */
class Assignment2 extends AssignmentGeneral
{
//...
}

Solution

  • Class table inheritance ('JOINED') doesn't require the parent class to be abstract.

    Besides, one of the benefits of inheritance is to get the parent's properties when you instantiate a child class. So you don't have to instantiate both, just instantiate Assignment1 or Assignment2.

    Add relations to both of them in the Course entity and an assignmentType property so that you know which one it's linked to.