blahblah
blahblah

Reputation: 1018

Doctrine: update column on insert in other table

I have 2 entities: Service and Session with one-to-many relationship

 class Service{
     /**
      * @var int
      *
      * @ORM\Column(name="avg_score", type="integer")
      */
     private $avgScore;

     /**
      * @ORM\OneToMany(targetEntity="Session", mappedBy="service")
      */
      private $sessionList;
 }

 class Session{
      /**
       * @ORM\ManyToOne(targetEntity="Service", inversedBy="sessionList")
       * @ORM\JoinColumn(name="service_id", referencedColumnName="id")
       */
      private $service;

       /**
        * @var int
        *
        * @ORM\Column(name="score", type="integer", nullable=true)
        */
        private $score;
 }

With Doctrine QueryBuilder how can I update $avgScore of Service entity everytime new Session with $score is created?

This is what I tried to do:

   $qb = $this->getDoctrine()->getEntityManager()->createQueryBuilder();
    $q = $qb->update('AppBundle:Service', 's')
        ->join('AppBundle:Session', 'ss')
        ->addSelect('avg(ss.score) as score_avg')
        ->groupBy('ss.service')
        ->set('s.avgScore', 'score_avg')
        ->where('s.id = ?1')
        ->setParameter(1, $service->getId())
        ->getQuery();
    $q->execute();

Upvotes: 0

Views: 536

Answers (1)

Dmitry Malyshenko
Dmitry Malyshenko

Reputation: 3051

You need to create a Doctrine Events Listener

services:
    my.listener:
        class: AppBundle\EventListener\AvgScoreUpdater
        tags:
            - { name: doctrine.event_listener, event: prePersist }

And then in AvgScoreUpdater implement logic:

class AvgScoreUpdater
{
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if (!($entity instanceof Session) || !$entity->getScore()) {
            return;
        }

        $entityManager = $args->getEntityManager();

        $service = $entity->getService();
        // Then realize logic to update avg_score on a service
    }
}

Upvotes: 1

Related Questions