多态附件使用学说2中的多态关系的子集

Bea*_*eve 7 filesystems polymorphic-associations symfony doctrine-orm

我需要一些使用"多态关联"的学说2的帮助.让我澄清一下自己.实体可以使用多态关系的子集来支持文件附件.File实体用于保护这种关系,其中对文件的引用作为记录存储在files表中,并与父模型具有多态关系.我想创建与https://octobercms.com/docs/database/attachments相同的功能 但是不知道如何建立关系,以及如何使attachment_typeattachment_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;
Run Code Online (Sandbox Code Playgroud)

文件表的一个例子.

文件表的一个例子

grs*_*ssn 0

我在尝试在 symfony 中实现多态性(包括多态文件)方面有一些经验,这次我想我可以与您分享一些我的见解,希望它们能为您提供一些有关该主题的有用信息。

首先,我建议阅读学说链接中的继承映射。通过学说继承映射,您只需创建一个主 File 类,然后让所有其他附件扩展它。然后,假设您要向用户添加图片附件。您只需在用户和主 File 类之间创建一对一关系。如果您保留的附件是附件类之一的实例,则 Doctrine 足够聪明,可以返回该类的对象,而不是主 File 类。

为了回答你的问题,我给你举一个具体的例子。案件

  • ImageAttachment 扩展了 FileAttachment
  • 用户有一个名为照片的属性
  • 属性照片是与 FileAttachment 实体的 OneToOne 关系

代码:

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

$em->persist($user);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

结果:

现在,在数据库的 User 表中,在名为 photo_id 的列中,引用的 ID 将是 FileAttachment 表中的 ID。当你执行 $user->getPhoto(); 时 它将返回一个 ImageAttachment 类的对象,因为学说知道您保留了一个 ImageAttachment,而不仅仅是一个 FileAttachment。


当谈到收藏时,事情也会非常简单。在这种情况下,您可能需要在文件和要与该文件关联的实体之间创建多对多关系。假设用户可以在数据库中保存许多不同类型的附件。如果您想在广泛的应用程序中使用此文件系统,那么文件了解其所属的用户可能是没有意义的,因为很快文件就必须保存有关所有不同类型关系的信息,而这不是一个智能架构如果您想要安装任何类型的模块化系统,请选择。这就是为什么我的建议是在某些实体和附件之间使用多对多关系。这样,只有用户知道数据库中的文件,文件系统将是不可知的和解耦的。

在谈论学说中的多态性时要指出的第三个要点是 symfony 对这一功能的支持。一般来说,多态性在某些情况下被认为是一种不好的做法,特别是在数据持久性方面并没有得到社区的太多支持。因此,需要考虑的一件重要事情是 symfony CollectionType 不支持多态性。基本上,如果您计划使用多态形式集合,则必须编写自己的类型。但如果您不介意使用一点 ajax,这并不是真正的问题,您可以简单地避免仅出于此目的使用 SF 表单。