引用 id 上的鉴别器

Discriminator on referenced id

我的标题可能不是最好的描述,但这是我能想到的最好的。

我有 4 个实体; Page、PageElement、Image 和一个名为 TextWithImage 的实体。 Page 包含 pageElements(PageElement 实体数组)。这些 pageElement 可以有多种类型,但目前我只有一个名为 TextWithImage 的类型,它保存了 PageElement 实体保存的数据的附加数据。

PageElement 可以包含在许多页面上,因此,我在 PageElement.orm.yml 中有一个 ManyToMany。 TextWithImage 有一个 manyToOne 来引用 Image。

(更多信息:另一个 Entity ImageGallery 可能与 Image 实体存在多对多关系,而 TextOnly 不应该对 Image 实体有任何引用。)

我希望能够获取页面并检索具有所有 "attributes" 的页面元素。假设我请求获得一个只有一种 TextWithImage 类型的 PageElement 的页面,我想 return 以下内容。

Page -> pageElements = array (
    [0] => TextWithImage -> image = Image -> filename = "image.png"
                                          -> alt = "An image!"
                         -> text  = "There's an image too!"
)

一切看起来都很简单,但我需要理论来理解这个 PageElement 是一个 TextWithImage 类型。我可以用 DiscriminatorColumn 来做到这一点吗(粗略的草图);

Table: pageelement
id | attributes | discr | TextWithImageId

Table: textwithimage
id | attributes

请记住,我将拥有不止一种类型的 PageElement,而不仅仅是 TextWithImage。

这可能吗?如果可能,怎么做?

我找到了解决问题的办法。这些是 doctrine YML 文件。您可以使用 php app/console doctrine:generate:entities AppBundle/Entity 生成所有实体。 确保 PageTextImageElement class 扩展了 PageElement class。

Page.orm.yml

AppBundle\Entity\Page:
    type: entity
    table: null
    repositoryClass: AppBundle\Repositories\PageRepository
    manyToMany:
        pageElements:
            targetEntity: PageElement
            cascade: ["all"]
            joinTable:
                name: null
                joinColumns:
                    page_id:
                        referencedColumnName: id
                        onDelete: CASCADE
                inverseJoinColumns:
                    page_element_id:
                        referencedColumnName: id
                        unique: true
                        onDelete: CASCADE
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        name:
            type: string
            length: '255'
            unique: true
    lifecycleCallbacks: {  }

PageElement.orm.yml

AppBundle\Entity\PageElement:
    type: entity
    inheritanceType: SINGLE_TABLE
    discriminatorColumn:
        name: discr
        type: string
    discriminatorMap:
        pageTextImageElement: PageTextImageElement
    table: null
    repositoryClass: AppBundle\Repositories\PageElementRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        sortOrder:
            type: integer
        attributes:
            type: array
            nullable: true
    lifecycleCallbacks: {  }

PageTextImageElement.orm.yml

AppBundle\Entity\PageTextImageElement:
    type: entity
    table: null
    oneToOne:
        image:
            targetEntity: AppBundle\Entity\Image
            joinColumn:
                name: imageId
                referencedColumnName: id
    fields:
        passage:
            type: string
            length: '255'
    lifecycleCallbacks: {  }

Image.orm.yml

AppBundle\Entity\Image:
    type: entity
    table: null
    repositoryClass: AppBundle\Repositories\ImageRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        name:
            type: string
            length: '255'
            unique: true
        description:
            type: string
            length: '255'
    lifecycleCallbacks: {  }