Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Target entity Doctrine 2 and Symfony 2

I want dynamic entity mapping on one entity which will be used by other entities. For example, I have a File entity, which will store MIME type, mapping key, name etc, also an entity_id which will contain the id to the entity it belongs to. The mapping key will determine the class as this file entity will be many-to-many. So the targetEntity for File entity isn't fixed. How to achieve that?

File Entity

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * File
 *
 * @ORM\Entity
 */
class File {
    //.... Other mapping properties

    /**
     * @ORM\ManyToOne(targetEntity="SuperClass", inversedBy="files")
     * @ORM\JoinColumn(name="entity_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $entity;
}

Product Entity

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Product
 *
 * @ORM\Entity
 */
class Product extends SuperClass {
    //.... Other mapping properties

    /**
     * @ORM\OneToMany(targetEntity="File", mappedBy="entity")
     */
    protected $files;
}

But I have many other entities similar to Product and how do I make sure that when I call getFiles(), I get the files of the respective entity. I think it may work like this anyway, but is this the right way, or is there a better way?

like image 247
deviprsd Avatar asked Oct 18 '22 13:10

deviprsd


1 Answers

Ok, this is a very common problem I have - how to link one entity to many others which are very similar.

First, reevaluate: I often find, that I don't actually need that many different entities and that they can be folded into one there by simplifying everything. We often overengineer and overcomplicate when we don't really have to (or even shouldn't)!

If that's not an option: create separate relationships between File and all other (relevant) entities. Yes, your file entity will be full of relationships. Then write one general access getter that computes which entity it is connected to and returning it (either by going through all connections or it can be more involved that that [and faster] by computing it from other params (like mime type in your case). This way you hide the complexity of all those relationsip from the rest of your code.

This option works if you just need a good enough solution. A more correct one would be to forgo doctrine relations and track IDs and related entities classes in two fields and select and instantiate the objects yourself (in the entity, ofcorse). But that's more involved and more error prone.

If you find a way to do this in a more elegant, doctrine2 backed way, please do let me (and the rest of us) know.

like image 54
Putr Avatar answered Oct 21 '22 05:10

Putr