4
votes

I have need to create this database scheme in Symfony Entities :

ClassA:

  • id
  • name
  • ... some other attributes only for class A

ClassB:

  • id
  • name
  • ... some other attributes only for class B

ClassC:

  • id
  • name
  • ... some other attributes only for class C

Course:

  • id
  • name
  • type
  • class_id
  • class_type [A, B, C]
  • ...

I need to create relations between Course Entity (using the class_id) with the other entities (ClassA, ClassB, ClassC) (using the id) and using the class_type (A, B, C).

A Course is not a class and a class is not a course. There is no inheritance here. In my project I'm using this concept (id and type to map different entities). So I need to solve this problem with a simple example like this one

I thought about using @ORM\DiscriminationMap here:

/**
 * Course
 *
 * @ORM\Table(name="Course")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="course_type", type="string")
 * @ORM\DiscriminatorMap({"A" = "ClassA", "B" = "ClassB", "C" = "ClassC"})
 */
abstract class Course
{
 //...
}

class ClassA extends Course
{
 //...
}

class ClassB extends Course
{
 //...
}

class ClassC extends Course
{
 //...
}

Or something like this.

But I don't want to copy the Course's attributes in the ClassA, ClassB, ClassC entities because "extends" will copy the parent entity's attributes to the child.

It's not about inheritence. I need to keep the database scheme described above without adding any additional attributes from the other entities.

Thank you

1
So as i understand you need relation between Class(A|B|C) and Course ? is it two different database tables right? - Petro Popelyshko
Thank you for your response. Yes they are 4 entities (database tables). The relation should be based on the Course.class_type - Mohamed Aymen Karmous

1 Answers

3
votes

Solution might be next:

use Doctrine\ORM\Mapping as ORM;
    /**
     * @ORM\Entity
     * @ORM\Table(name="class")
     * @ORM\InheritanceType("JOINED")
     * @ORM\DiscriminatorColumn(name="type", type="string", length=20)
     * @ORM\MappedSuperclass
     * @ORM\DiscriminatorMap({
     *     "class_a" = "ClassA",
     *     "class_b" = "ClassB",
     *     "class_c" = "ClassC"
     * })
     */
    abstract class AbstractClass
    {
       ... common fields
        /**
         * @var PersistentCollection
         *
         * @ORM\OneToMany(targetEntity="Course", cascade={"persist"}, mappedBy="course")
         */
        protected $courses;

    }
   /**
    * @Entity
    * @ORM\Table(name="class_a")
    */
    class ClassA extends AbstractClass
    {
     //...
    }
   /**
    * @Entity
    * @ORM\Table(name="class_b")
    */
    class ClassB extends AbstractClass
    {
     //...
    }
   /**
    * @Entity
    * @ORM\Table(name="class_c")
    */
    class ClassC extends AbstractClass
    {
     //...
    }

   /**
    * @Entity
    * @ORM\Table(name="course")
    */
    class Course
    {

        /**
         * @var AbstractClass
         * @ORM\ManyToOne(targetEntity="AbstractClass", inversedBy="course")
         * @ORM\JoinColumn(onDelete="CASCADE")
         */
        private $course;
        ....

    }

So now you'll have single table for all your classes with one to many relation to course(this is just an example, you could use one to many or many to many, depends on your needs).

Within DQL you can find out which class is used with INSTANCE OF.