Инициализировать отношение «многие ко многим» в Symfony3/Doctrine2

Отредактировано: отношения «многие ко многим» вместо «один ко многим»

Данные сущности: Пользователь и Элемент.

Элемент имеет логическое свойство с именем: $mandatory.

Пользователь связан с многими-ко-многим элементами.

При создании/конструкции нового Пользователя он должен быть связан (инициализирован) с каждым Элементом, у которого для свойства ($mandatory) установлено значение истинный.

Как лучше всего выполнить эти требования в Symfony3/Doctrine2?


person medunes    schedule 17.09.2017    source источник
comment
Вы уверены, что это отношение OTM, а не MTM?   -  person M Khalid Junaid    schedule 17.09.2017
comment
Отредактировано: связь «многие ко многим» вместо «один ко многим»   -  person medunes    schedule 17.09.2017


Ответы (2)


Создайте подписчика событий, как описано здесь:

http://symfony.com/doc/current/doctrine/event_listeners_subscribers.html#creating-the-subscriber-class

public function getSubscribedEvents()
{
    return array(
        'prePersist',
    );
}

public function prePersist(LifecycleEventArgs $args)
{
    $entity = $args->getObject();

    if ($entity instanceof User) {
        $entityManager = $args->getEntityManager();
        // ... find all Mandatody items and add them to User
    }
}

добавьте функцию prePersist (если вы хотите только при создании), проверьте, является ли это объектом пользователя, получите все элементы из базы данных, которые являются обязательными, и добавьте их в объект пользователя.

person kunicmarko20    schedule 17.09.2017

Я пришел к этому решению, вдохновленный подсказкой @kunicmarko20 выше.

Мне пришлось подписаться на событие preFlush(), а затем использовать объект UnitOfWork через аргумент PreFlushEventArgs, чтобы получить объекты, запланированные для вставки.

Если я встречаю экземпляр User таких сущностей, я просто добавляю в него все обязательные элементы.

Вот код:

<?php
// src/AppBundle/EventListener/UserInitializerSubscriber.php
namespace AppBundle\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreFlushEventArgs ;

use AppBundle\Entity\User;
use AppBundle\Entity\Item;


class UserInitializerSubscriber implements EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(
            'preFlush',
        );
    }

    public function preFlush  (PreFlushEventArgs  $args)
    {
        $em     = $args ->getEntityManager();
        $uow    = $em   ->getUnitOfWork();


         // get only the entities scheduled to be inserted
        $entities   =   $uow->getScheduledEntityInsertions();
        // Loop over the entities scheduled to be inserted    
        foreach ($entities as $insertedEntity) {
            if ($insertedEntity  instanceof User) {
                $mandatoryItems = $em->getRepository("AppBundle:Item")->findByMandatory(true);
                // I've implemented an addItems() method to add several Item objects at once                    
                $insertedEntity->addItems($mandatoryItems);

            }   
        }
    }
}

Надеюсь, это поможет.

person medunes    schedule 20.09.2017