简体   繁体   中英

Doctrine 2 - Relate from abstract class to abstract class

Alright. This question is kind of hard to describe. But here goes. I'll post some images first, just incase someone gets what I'm doing from this image;

在此输入图像描述

A Block is an element that can be used to fill a webpage or blogpost. This can be images, text or forms. These Blocks are ContentBlocks. Block has a DiscriminatorColumn and DiscriminatorMap properties that are used to join the right Block table and create the underlying Block element. (ie an ImageContentBlock)

On the other hand we have Forms. Forms consist of FormBlocks. These are certain common Form elements. (TextField, PhoneField etc).

I want to be able to relate to the Content- or FormBlocks from either Page, Post or Form.

How can I achieve this in Doctrine?

I could add an entityType and entityId field to the Block class. But that would remove the object orientated style of programming. I would rather refer to the owning ContentEntity. But then again. I need to join or relate to the Blocks.

Not every ContentEntity has Blocks. So I cannot add this as an property of ContentEntity.

Now. I could off course use a ManyToMany relationship and go with a JoinTable. I guess that would always work. But I would have to join twice.

I think your problem isn't primarily about the data relations but about the fact that you want to avoid duplicate code. This results in your “Entity” being at the top of your hierarchy, only because it has a few common properties that each entity should have. (By the way, naming an entity “Entity” is a bit confusing.)

Maybe what you're looking for are Traits . So, instead of providing id and active through an entity, it could as well be a trait:

trait CmsEntity
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="boolean")
     */
    protected $active;

    // add getters/setters and other code as you like
}

Now you can attach this trait to all the entities which should have the given properties.

/**
 * @ORM\Entity
 */
class Page
{
    use CmsEntity; // import the trait

    /**
     * @ORM\Column(type="text")
     */
    private $header;

    //  etc.
}

This will make you free from the requirement of deriving all your entities from one master “Entity” which just carries some common properties.

And now you can create a direct relation between between “ContentEntity” and “Block” (1:n I'd guess), which is more logical.

There's also a nice article elaborating on using Doctrine with traits for further reading.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM