Я застрял на этом. Вот что я получил:
Я получил Document
Entitiy, который может иметь $previosDocuments
а также $nextDocuments
. Это отношение bidirectional
и оба они ArrayCollections
, Но мне также нужно знать некоторую другую дополнительную информацию. Вот почему я получил DocumentRelation
-Объект, который содержит дополнительные поля.
Замечания: Я знаю, что приведенный ниже код не является правильным на всех.
Это мой код до сих пор:
/**
* @ORM\Entity
* @ORM\Table(name="document")
*/
class Document
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string $name
* @ORM\Column(type="string")
*/
protected $name;
/**
* @var ArrayCollection $nextDocuments
* @ORM\OneToMany(targetEntity="App\FrontEndBundle\Entity\DocumentRelation", mappedBy="document", cascade={"persist"})
*/
protected $nextDocuments;
/**
* @var ArrayCollection $prevDocuments
* @ORM\OneToMany(targetEntity="App\FrontEndBundle\Entity\DocumentRelation", mappedBy="targetDocument", cascade={"persist"})
*/
protected $prevDocuments;
/**
* Document constructor.
*/
public function __construct()
{
$this->prevDocuments = new ArrayCollection();
$this->nextDocuments = new ArrayCollection();
}
/**
* @param Document $nextDocument
* @return $this
*/
public function removeNextDocument($nextDocument)
{
if ($this->nextDocuments->contains($nextDocument)) {
$this->nextDocuments->removeElement($nextDocument);
$nextDocument->removePrevDocument($this);
}
return $this;
}
/**
* @param Document $nextDocument
* @return $this
*/
public function addNextDocument($nextDocument)
{
if (!$this->nextDocuments->contains($nextDocument)) {
$this->nextDocuments->add($nextDocument);
$nextDocument->addPrevDocument($this);
}
return $this;
}
/**
* @param Document $prevDocument
* @return $this
*/
public function addPrevDocument($prevDocument)
{
if (!$this->prevDocuments->contains($prevDocument)) {
$this->prevDocuments->add($prevDocument);
$prevDocument->addNextDocument($this);
}
return $this;
}
/**
* @param Document $prevDocument
* @return $this
*/
public function removePrevDocument($prevDocument)
{
if ($this->prevDocuments->contains($prevDocument)) {
$this->prevDocuments->removeElement($prevDocument);
$prevDocument->removeNextDocument($this);
}
return $this;
}
//getter + setter
}
/**
* Class DocumentRelation
* @package App\FrontEndBundle\Entity
* @ORM\Entity
* @ORM\Table(name="document_relation")
*/
class DocumentRelation
{
/**
* @var Document $targetDocument
* @ORM\ManyToOne(targetEntity="App\FrontEndBundle\Entity\Document", inversedBy="id")
* @ORM\JoinColumn(name="target_document_id", referencedColumnName="id")
*/
protected $targetDocument;
/**
* @var Document $document
* @ORM\ManyToOne(targetEntity="App\FrontEndBundle\Entity\Document", inversedBy="id")
* @ORM\JoinColumn(name="document_id", referencedColumnName="id")
*/
protected $document;
[...] //$id & getter + setter
}
Моя проблема в том, что я не знаю, как заставить их работать вместе.
За любую идею, помощь или подсказку буду очень благодарен!
РЕДАКТИРОВАТЬ:
В конце я хочу получить самоссылающуюся сущность с двунаправленной связью и некоторыми дополнительными полями для хранения дополнительной информации о двунаправленной связи.
РЕДАКТИРОВАТЬ 2 @ Куба-Birecki:
public function indexAction()
{
$this->createDocuments();
return $this->render('AppFrontEndBundle:Default:index.html.twig');
}
private function createDocuments()
{
$firstDocument = (new Document())->setName('first');
$secondDocument = (new Document())->setName('second');
$firstDocument->addNextDocument($secondDocument);
$em = $this->getDoctrine()->getManager();
$em->persist($firstDocument);
$em->flush();
}
Это способ, которым я пытаюсь сохранить это, и это также, как я должен назвать это.
Исключение ниже
Найденная сущность типа App \ FrontEndBundle \ Entity \ Document в ассоциации App \ FrontEndBundle \ Entity \ Document # nextDocuments, но ожидающая App \ FrontEndBundle \ Entity \ DocumentRelation
Ваши аннотации выглядят хорошо, но ваша бизнес-логика не отражает эти правила.
$nextDocuments
из Document
класс должен содержать коллекцию DocumentRelation
, но в ваших методах вы пытаетесь вставить Document
объекты там. То же самое касается $prevDocuments
,
Все, что вам нужно изменить Document
класс для работы DocumentRelation
объекты вместо Document
:
class Document
{
...
/**
* @param DocumentRelation $relation
* @return $this
*/
public function removeNextDocument(DocumentRelation $relation)
{
if ($this->nextDocuments->contains($relation)) {
$this->nextDocuments->removeElement($relation);
$relation->setDocument(null);
}
return $this;
}
/**
* @param DocumentRelation $relation
* @return $this
*/
public function addNextDocument(DocumentRelation $relation)
{
if (!$this->nextDocuments->contains($relation)) {
$this->nextDocuments->add($relation);
$relation->setDocument($this);
}
return $this;
}
/**
* @param DocumentRelation $relation
* @return $this
*/
public function addPrevDocument(DocumentRelation $relation)
{
if (!$this->prevDocuments->contains($relation)) {
$this->prevDocuments->add($relation);
$relation->setTargetDocument($this);
}
return $this;
}
/**
* @param DocumentRelation $relation
* @return $this
*/
public function removePrevDocument(DocumentRelation $relation)
{
if ($this->prevDocuments->contains($relation)) {
$this->prevDocuments->removeElement($relation);
$relation->setTargetDocument(null);
}
return $this;
}
}
Конечно, это также означает, что вы должны создать / получить эти DocumentRelation
объекты перед передачей их этим методам.
Затем, если, например, вы хотите проверить, $prevDocuments
содержит определенный Document
передавая его непосредственно вместо DocumentRelation
, вы бы сделали это так:
public function hasPrevDocument(Document $document)
{
// Iterate over DocumentRelations
foreach ($this->prevDocuments as $relation) {
// Check if the relation refers to the wanted document
if ($relation->getDocument() === $document) {
return true;
}
}
return false;
}
Надеюсь, это поможет.
Других решений пока нет …