medunes
medunes

Reputation: 586

Initialize a Many-To-Many relationship in Symfony3/Doctrine2

Edited: Many to Many relationship instead of One To Many

Given entities: User & Item.

Item has a boolean property named: $mandatory.

User is related to Many-To-Many Items.

At the creation/construction of a new User, he must be related (initialization) to every Item that has ($mandatory) property set to true.

What is the best practice to ensure these requirements in Symfony3/Doctrine2 ?

Upvotes: 0

Views: 557

Answers (2)

medunes
medunes

Reputation: 586

I came to this solution, inspired by @kunicmarko20 's hint above.

I had to subscribe to the preFlush() event, then, use the UnitOfWork object through the PreFlushEventArgs argument to get the entities scheduled for insertion.

If I encounter a User instance of such entities, I just add all mandatory items to it.

Here is the code:

<?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);

            }   
        }
    }
}

I hope this helps.

Upvotes: 0

kunicmarko20
kunicmarko20

Reputation: 2180

Create an event subscriber like explained here:

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
    }
}

add prePersist function (if you only want on creation) check if it is the User object, get all items from the database that are mandatory and add them to User Entity.

Upvotes: 3

Related Questions