Polymorphic attachments using a subset of the polymorphic relationship in doctrine 2
Asked Answered
D

1

7

I need some help with doctrine 2 that uses "polymorphic associations". Let me clarify myself. Entitys can support file attachments using a subset of the polymorphic relationship. the File entity is used to safekeep this relationship where reference to the files are stored as records in the files table and have a polymorphic relation to the parent model. I want to create the same functionality as https://octobercms.com/docs/database/attachments But do not know how to make the relationship, and how, for example, put the attachment_type dynamic like attachment_id;

 /**
 * @var \Doctrine\Common\Collections\ArrayCollection
 *
 * @ORM\OneToOne(targetEntity="App\Domain\FileAttachment\Entity\FileAttachment", attachment_type="news_thumbnail")
 */
private $thumbnail;


/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 *
 * @ORM\OneToOne(targetEntity="App\Domain\FileAttachment\Entity\FileAttachment", attachment_type="news_image")
 */
private $image;

/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 *
 * @ORM\OneToMany(targetEntity="App\Domain\FileAttachment\Entity\FileAttachment", attachment_type="news_files")
 */
private $files;

An example of the files table.

An example of the files table

Dupin answered 21/3, 2017 at 12:7 Comment(0)
M
0

I have some experience in trying to make polymorphism work (including polymorphic files) in symfony and by this time I think I can share a few of my insights with you in hopes that they would provide you with some useful information about this subject.

Firstly, I would suggest reading up on inheritance mapping in doctrine link. With doctrine inheritance mapping you would simply create one main File class and then make every other attachment extend it. Then, say you want to add a picture attachment to the user. You would simply create a oneToOne relationship between the user and the main File class. If the attachment you persist would be an instance of one of the attachment classes, Doctrine is smart enough to return you an object of that class, not the main File class.

So to answer you question, I will give you a specific example. Case:

  • ImageAttachment extends FileAttachment
  • User has a property called photo
  • Property photo is a OneToOne relationship to the FileAttachment entity

Code:

$image = new ImageAttachment();
$user->setPhoto($image);

$em->persist($user);
$em->flush();

Result:

Now in the database in the User table, in a column called something like photo_id the referenced ID would be the one in the FileAttachment table. When you would do $user->getPhoto(); it would return an object of class ImageAttachment since doctrine knows that you have persisted an ImageAttachment, not just a FileAttachment.


When it comes to collections, things would also be pretty simple. In this case, you would probably need to create an ManyToMany relationship between the file and the entity that you want to relate to the file. Say that a user can have many different types of attachments saved in the database. If you want to use this filesystem application wide it would probably make no sense for a file to know about the user it belongs to, because soon file would have to hold information on all different types of the relationships and that is just not a smart architecture choice if you want to have any type of modular system in place. Thats why my suggestion is to use ManyToMany relationships between some entity and the attachments. This way only user would know about the files in the database and filesystem would be agnostic and decoupled.

A third important point to be made when talking about polymorphism in doctrine is symfony support for this feature. Generally polymorphism is considered to be somewhat of a bad practice in certain cases, and especially in data persistence does not have much support in the community. So an important thing to consider is that symfony CollectionType HAS NO SUPPORT FOR POLYMORPHISM what so ever. Basically you will have to write your own Type if you were planning on using polymorphic form collections. But if you don't mind using a bit of ajax, this is not really a problem, you can simply avoid using SF forms for this purpose alone.

Maimonides answered 27/3, 2017 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.