2016-09-23 2 views
-1

Мне не ясно, как обрабатывать операции со стороны OneToMany.Операции отношения OneToMany в доктрине-symfony

Скажем, объект A находится на стороне ManyToOne, а объект B - на стороне OneToMany.

  1. Я хочу, чтобы при создании объекта B, чтобы присвоить многие объекты А к ней - мое решение в этом было для выборки объектов A и присвоить им объект B

  2. Я хочу при удалении объект B, чтобы установить на нуль все ссылки из объектов А - от исследования я вижу, что, возможно, придется добавить ondelete="setNull" функциональность на столе

ли Ther лучший способ (или альтернативы в целом) справиться с этой ситуацией?

+0

Просто отформатирован для ясности –

ответ

0
use Doctrine\ORM\Mapping as ORM; 

class AObject 
{ 
    // ... 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\BObject", inversedBy="a", onDelete="SET NULL") 
    */ 
    private $b; 
} 

class BObject 
{ 
    // ... 

    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\AObject", mappedBy="b", cascade={"persist"}) 
    */ 
    private $a; 

    public function __construct() 
    { 
     $this->a = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * @return \Doctrine\Common\Collections\ArrayCollection 
    */ 
    public getA() 
    { 
     return $this->a; 
    } 

    /** 
    * @param \Doctrine\Common\Collections\ArrayCollection $a 
    */ 
    public setA($a) 
    { 
     $this->a = $a; 
    } 

    /** 
    * @param AObject $a 
    * @return BObject 
    */ 
    public addA($a) 
    { 
     $this->a[] = $a; 
     $a->setB($this); // assign B object to A 

     return $this; // For method chaining 
    } 

    /** 
    * @param AObject $a 
    */ 
    public removeA($a) 
    { 
     $this->a->removeElement($a); 
    } 
} 

Для 1) вам все равно придется извлекать ваши объекты, ваш код не сможет волшебным образом узнать, какие объекты назначаются вашему новому B-объекту.

С класса В, определенной выше, вы можете написать

$b = new BObject(); 
$b 
    ->addA($a1) 
    ->addA($a2) 
    ->addA(new AObject()); 
$entityManager->persist($b); 
$entityManager->flush(); 

и А объекты будут иметь ссылку на Б.

Для 2) это еще лучшее решение, справиться с уровнем базы данных ,

0

Для ваших целей вы можете использовать doctrine lifecycle events.

Для образца, сначала необходимо определить слушатель события:

# /src/FooBundle/Resources/config/services.yml 
services: 

# Event subscribers 
foo.bar.subscriber: 
    class: FooBundle\EventListener\BarSubscriber 
    tags: 
     - { name: doctrine.event_subscriber } 

Затем создайте один:

// FooBundle\EventListener\BarSubscriber.php 
namespace FooBundle\EventListener; 

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

class BarSubscriber implements EventSubscriber 
{ 
    public function getSubscribedEvents() 
    { 
     return array(
      'preRemove', 
      'postPersist', 
     ); 
    } 

    // This method will be executed on each entity, before it has been deleted 
    // You can do here what u want in your second paragraph 
    public function preRemove(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     // Do not forget to check your entity type 
     if (!$entity instanceof SomeInterface) { 
      return; 
     } 

     // Some code that handle some actions on related entites 
    } 

    // This code will be executed after each entity creation 
    // Here you can add more relations for your main entity 
    public function postPersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 
     if (!$entity instanceof TimestampableInterface) { 
      return; 
     } 

     // Some actions on relations, after the establishment of the main object 
    } 
} 

Кроме того, в качестве альтернативы, вы можете использовать Doctrine cascade operations, для удаления всех дочерних entites

Смежные вопросы