Сделать полиморфную связь для комментариев?

В Symfony полиморфная связь для комментариев реализуется через использование полиморфных связей Doctrine и специальных аннотаций.

Для начала определим модели данных, которые будут связаны с комментариями. Например, у нас есть модели "Пост" и "Статья", и мы хотим добавить комментарии к этим моделям.

1. Создайте модель "Комментарий" с необходимыми полями, такими как текст комментария, дата создания и т.д. Эта модель будет содержать поле с названием "targetEntity" для хранения имя целевой сущности (например, "Post" или "Article").

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
 * @ORMEntity()
 */
class Comment
{
    // ...

    /**
     * @ORMColumn(type="string")
     */
    private $targetEntity;

    /**
     * @ORMColumn(type="integer")
     */
    private $targetEntityId;

    // ...
}

2. Определите модели "Пост" и "Статья" с помощью Doctrine и добавьте отношение OneToMany к комментариям.

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
 * @ORMEntity()
 */
class Post
{
    // ...

    /**
     * @ORMOneToMany(targetEntity="AppEntityComment", mappedBy="targetEntity")
     */
    private $comments;

    // ...
}

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
 * @ORMEntity()
 */
class Article
{
    // ...

    /**
     * @ORMOneToMany(targetEntity="AppEntityComment", mappedBy="targetEntity")
     */
    private $comments;

    // ...
}

3. Теперь, чтобы связать комментарий с конкретной моделью (постом или статьей), мы должны указать тип и идентификатор целевой сущности в полях "targetEntity" и "targetEntityId" комментария. Не забудьте установить соответствующие геттеры и сеттеры в классе "Comment".

namespace AppEntity;

use DoctrineORMMapping as ORM;

/**
 * @ORMEntity()
 */
class Comment
{
    // ...

    public function setTargetEntity($entity)
    {
        $this->targetEntity = get_class($entity);
        $this->targetEntityId = $entity->getId();
    }

    public function getTargetEntity()
    {
        return $this->targetEntity;
    }

    public function getTargetEntityId()
    {
        return $this->targetEntityId;
    }

    // ...
}

4. Теперь, когда у нас есть связи и правильные методы сохранения и получения целевой сущности комментария, мы можем легко добавлять комментарии к постам или статьям.

// ... Код контроллера или сервиса

use AppEntityComment;
use AppEntityPost;
use AppEntityArticle;

// Создаем комментарий к посту
$post = new Post();
// ... Заполнение полей поста

$comment = new Comment();
$comment->setText('Новый комментарий к посту');
$comment->setTargetEntity($post);
$entityManager->persist($comment);
$entityManager->flush();

// Создаем комментарий к статье
$article = new Article();
// ... Заполнение полей статьи

$comment = new Comment();
$comment->setText('Новый комментарий к статье');
$comment->setTargetEntity($article);
$entityManager->persist($comment);
$entityManager->flush();

Таким образом, мы создали полиморфную связь с использованием аннотаций Doctrine. Теперь у нас есть возможность добавлять комментарии к разным типам моделей.