Symfony,很多人都有自我引用的属性

时间:2017-12-04 11:38:11

标签: symfony many-to-many self-referencing-table

我有一个与自身具有ManyToMany关系的实体房间,这种关系(RoomLinkRoom)具有属性" weight" : 房间可以链接到多个房间,具有订购(重量)值(以及可能的其他属性)。

我有sofar的代码处理一个或多个RoomTo与RoomFrom的链接。 我们说我们有: 房间A:1 RoomB:2

在会议室表格中,我们可以将RoomB添加到RoomA 我们在RoomLinkRoom中有这个条目:

RoomFromId:1 RoomToId:2

但这只是我需要的一半:我还需要反向部分管理。

当RoomFromId时,1链接到RoomToId,2 我还想添加这个中间实体:RoomFromId,2,RoomToId,1

然后我还要管理删除部分:如果我删除了房间A,则条目(roomFrom,roomTo):( 1,2)将被删除但反向(2,1) )也必须删除。

我怎样才能做到这一点?处理这整个问题的最好(最干净?)方法是什么?是否有"标准模式" ("自动"或不)处理这种情况? 我不确定如何处理,但也许它涉及事件,如postFlush?但它是否能够照顾"反向"删除? (到)方?

实体的(相关部分)是:

<?php

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use MyBundle\Entity\RoomLinkRoom;

/**
 * Room
 *
 * @ORM\Table(name="room")
 * @ORM\Entity(repositoryClass="MyBundle\Repository\RoomRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Room
{
  /**
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="IDENTITY")
   */
  private $id;

  /**
   * @ORM\Column(name="name", type="string", length=255, nullable=false)
   */
  private $name;

  /**
   * @ORM\OneToMany(
   *    targetEntity="MyBundle\Entity\RoomLinkRoom", mappedBy="roomFrom",
   *    cascade={"persist", "remove"}, orphanRemoval=TRUE)
   */
  private $roomFromLinks;

  /**
   * @ORM\OneToMany(
   *    targetEntity="MyBundle\Entity\RoomLinkRoom", mappedBy="roomTo",
   *    cascade={"persist", "remove"}, orphanRemoval=TRUE)
   */
  private $roomToLinks;

  public function __construct()
  {
    $this->roomFromLinks = new ArrayCollection();
    $this->roomToLinks = new ArrayCollection();
  }

  public function addRoomFromLink(RoomLinkRoom $roomFromLink)
  {
    $this->roomFromLinks[] = $roomFromLink;
    $roomFromLink->setRoomFrom($this);
    return $this;
  }

  public function removeRoomFromLink(RoomLinkRoom $roomFromLink)
  {
    $this->roomFromLinks->removeElement($roomFromLink);
  }

  public function getRoomFromLinks()
  {
    return $this->roomFromLinks;
  }

  public function addRoomToLink(RoomLinkRoom $roomToLink)
  {
    $this->roomToLinks[] = $roomToLink;
    $roomToLink->setRoomTo($this);
    return $this;
  }

  public function removeRoomToLink(RoomLinkRoom $roomToLink)
  {
    $this->roomToLinks->removeElement($roomToLink);
  }

  public function getRoomToLinks()
  {
    return $this->roomToLinks;
  }
}

并且

<?php
use Doctrine\ORM\Mapping as ORM;
use MyBundle\Entity\Room;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * RoomLinkRoom.
 *
 * @ORM\Table(name="roomlinkroom", indexes={
 *      @ORM\Index(name="FK_RoomLinkRoom_roomfromId", columns={"roomfromId"}),
 *      @ORM\Index(name="FK_RoomLinkRoom_roomtoId", columns={"roomtoId"}),
 * })
 * @ORM\Entity(repositoryClass="MyBundle\Repository\RoomLinkRoomRepository")
 * @UniqueEntity(
 *     fields={"roomFrom", "roomTo"},
 *     errorPath="weight",
 *     message="Ces salles sont déjà liées."
 * )
 */
class RoomLinkRoom
{
  /**
   * @var int
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

  /**
   * @ORM\ManyToOne(targetEntity="MyBundle\Entity\Room", inversedBy="roomFromLinks")
   * @ORM\JoinColumn(name="roomFromId", referencedColumnName="id", nullable=false)
   */
  private $roomFrom;

  /**
   * @ORM\ManyToOne(targetEntity="MyBundle\Entity\Room", inversedBy="roomToLinks")
   * @ORM\JoinColumn(name="roomToId", referencedColumnName="id", nullable=false)
   */
  private $roomTo;

  public function getId()
  {
      return $this->id;
  }

  public function setRoomFrom(Room $roomFrom)
  {
    $this->roomFrom = $roomFrom;
    return $this;
  }

  public function getRoomFrom()
  {
    return $this->roomFrom;
  }

  public function setRoomTo(Room $roomTo)
  {
    $this->roomTo = $roomTo;
    return $this;
  }


  public function getRoomTo()
  {
    return $this->roomTo;
  }
}

我已经尝试在控制器中添加冲洗后添加:

if ($form->isSubmitted() && $form->isValid()) {
//...
  $em->persist($room);
  $em->flush();

  //look for existing relationship between To and From
  foreach ($room->getRoomFromLinks() as $rfl){
    $res = $em->getRepository('MyBundle:RoomLinkRoom')
      ->findBy(['roomFrom' => $rfl->getRoomTo(), 'roomTo' => $room]);
    //add the reverse side
    if (count($res) === 0){
      $rlr = new RoomLinkRoom();
      $rlr->setRoomFrom($rfl->getRoomTo());
      $rlr->setRoomTo($room);
      $em->persist($rlr);
      $em->flush();
    }
  }
  //redirect
}

这增加了反向/补充条目,但我仍然不知道这是否干净/防错。但我确定这并不能解决删除问题。

所有人都使用过这种关系吗?

我在这里看过其他讨论(例如,this one)但是,他们似乎并不关心这个&#34;反向&#34;管理。

提前谢谢。

0 个答案:

没有答案