2

I have a number of unrelated entities that I'd like to be able to add FileAttachment entities to. I'm using Doctrine2 (in the context of a Symfony project).

Before I started using Doctrine, I'd make a junction table with a discriminator column, like this:

file_id
entity_id
entity_type

So far as I can tell, with Doctrine I'll require a junction table for each entity type that has FileAttachment associations. I'd prefer to avoid that if possible. I found an NHibernate solution here. Is it possible to do something similar with Doctrine and can anybody point me at some documentation? I've read (umpty times now!) chapters 6 and 7 of the Doctrine manual. But I'm not finding what I'm looking for.

Community
  • 1
  • 1
dnagirl
  • 20,196
  • 13
  • 80
  • 123

1 Answers1

2

Try creating an abstract FileAttachment class and extending it for each entity_type i.e. EntityOneAttachment, EntityTwoAttachment, etc.

The extended classes will all refer to the same join column entity_id but map it to their respective entities.

/**
 * @ORM\Entity
 * @ORM\Table(name="file_attachment")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="entity_type", type="string")
 * @ORM\DiscriminatorMap({"entity_one_attachment" = "EntityOneAttachment", "entity_two" = "EntityTwoAttachment"})
 */
abstract class FileAttachment
{          
  /**
   * @ORM\ManyToOne(targetEntity="File")
   * @ORM\JoinColumn(name="file_id", referencedColumnName="id", nullable=false)
  **/  
  protected $file;
}

/**
 * @ORM\Entity
 */
class EntityOneAttachment extends FileAttachment
{
  /**
   * @ORM\ManyToOne(targetEntity="EntityOne", inversedBy="fileAttachments")
   * @ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false)
  **/        
  protected $entityOne;
}

/** 
 * @ORM\Entity 
 */
class EntityTwoAttachment extends FileAttachment
{
  /**
   * @ORM\ManyToOne(targetEntity="EntityTwo", inversedBy="fileAttachments")
   * @ORM\JoinColumn(name="entity_id", referencedColumnName="id", nullable=false)
  **/        
  protected $entityTwo;  
}

Then map each Entity to its respective Attachment class.

class EntityOne
{
  /**
   * @ORM\OneToMany(targetEntity="EntityOneAttachment", mappedBy="entityOne")
  **/        
  protected $fileAttachments;
}
FuzzyTree
  • 32,014
  • 3
  • 54
  • 85
  • this would limit an attachment to being attached to only 1 entity, correct? – dnagirl Jun 10 '14 at 09:50
  • @dnagirl in this example each attachment object is mapped to exactly 1 file object and 1 entity object (think of it as a link between a file & entity) but different attachment objects can link to the same file or entity objects. – FuzzyTree Jun 10 '14 at 15:45