A
A
Anton2017-03-29 10:51:33
MySQL
Anton, 2017-03-29 10:51:33

How to organize Doctrine One-To-One, Unidirectional with Join Table?

I found in the Doctrine documentation how to do One-To-Many, Unidirectional with Join Table.
But I need One-To-One , Unidirectional with Join Table.
I have no idea how to do it.
The table structure is as follows: the document has a status. The status is associated with the document through the intermediate table exp_doc_status (which also stores the transition time to the status and additional information about the state of the status)

SQL code tables
--
-- Структура таблицы `exp_document`
--

CREATE TABLE `exp_document` (
  `id` mediumint(8) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Индексы таблицы `exp_document`
--
ALTER TABLE `exp_document`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `exp_document`
  MODIFY `id` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT;


--
-- Структура таблицы `exp_doc_status`
--

CREATE TABLE `exp_doc_status` (
  `id_doc` mediumint(8) UNSIGNED NOT NULL,
  `id_status` tinyint(2) UNSIGNED NOT NULL,
  `event_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `event_day` tinyint(2) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Индексы таблицы `exp_doc_status`
--
ALTER TABLE `exp_doc_status`
  ADD PRIMARY KEY (`id_doc`),
  ADD KEY `id_doc` (`id_doc`),
  ADD KEY `id_status` (`id_status`);

--
-- Ограничения внешнего ключа таблицы `exp_doc_status`
--
ALTER TABLE `exp_doc_status`
  ADD CONSTRAINT `exp_doc_status_ibfk_1` FOREIGN KEY (`id_status`) REFERENCES `exp_status` (`id`),
  ADD CONSTRAINT `exp_doc_status_ibfk_2` FOREIGN KEY (`id_doc`) REFERENCES `exp_document` (`id`);


--
-- Структура таблицы `exp_status`
--

CREATE TABLE `exp_status` (
  `id` tinyint(2) UNSIGNED NOT NULL,
  `name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Индексы таблицы `exp_status`
--
ALTER TABLE `exp_status`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для таблицы `exp_status`
--
ALTER TABLE `exp_status`
  MODIFY `id` tinyint(2) UNSIGNED NOT NULL AUTO_INCREMENT;

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton, 2017-03-29
@fattan

I did as Myroslav Berlad advised in the comment.
Detailed result:
documents linked to the intermediate table by a 1 to 1 two-way relationship
The intermediate table (document-status) was linked to the status table by a 1-to-many two-way relationship
. The database schema is the same, see header.
Created 3 entities.
For documents:

spoiler
<?php

namespace Finance\ExpBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * Document
 *
 * @ORM\Table(name="exp_document", indexes={@ORM\Index(name="tasks_user_id_index", columns={"initiator_id"})})
 * @ORM\Entity(repositoryClass="Finance\ExpBundle\Repository\DocumentRepository")
 */
class Document
{
    /**
     * @var integer
     *
     * @ORM\Column(name="initiator_id", type="integer", nullable=false)
     */
    private $initiatorId;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created_at", type="datetime", nullable=true)
     */
    private $createdAt;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated_at", type="datetime", nullable=true)
     */
    private $updatedAt;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;


    /**
     * One Customer has One Cart.
     * @var DocStatus
     * @ORM\OneToOne(targetEntity="DocStatus", mappedBy="document")
     */
    private $docStatus;


    /**
     * @return DocStatus
     */
    public function getDocStatus()
    {
        return $this->docStatus;
    }

    /**
     * @return Status
     */
    public function getStatus()
    {
        return $this->getDocStatus()->getStatus();
    }

    /**
     * Set initiatorId
     *
     * @param integer $initiatorId
     *
     * @return Document
     */
    public function setInitiatorId($initiatorId)
    {
        $this->initiatorId = $initiatorId;

        return $this;
    }

    /**
     * Get initiatorId
     *
     * @return integer
     */
    public function getInitiatorId()
    {
        return $this->initiatorId;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Document
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     *
     * @return Document
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     *
     * @return Document
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
}

For an intermediate table (document-status):
Spoiler
<?php

namespace Finance\ExpBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * DocStatus
 *
 * @ORM\Table(name="exp_doc_status", indexes={@ORM\Index(name="id_doc", columns={"id_doc"}), @ORM\Index(name="id_status", columns={"id_status"})})
 * @ORM\Entity
 */
class DocStatus
{
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="event_date", type="datetime", nullable=false)
     */
    private $eventDate = 'CURRENT_TIMESTAMP';

    /**
     * @var integer
     *
     * @ORM\Column(name="event_day", type="integer", nullable=false)
     */
    private $eventDay = '0';

    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $idDoc;


    /**
     * @ORM\OneToOne(targetEntity="Document", inversedBy="docStatus")
     * @ORM\JoinColumn(name="id_doc", referencedColumnName="id")
     */
    private $document;


    /**
     * @ORM\ManyToOne(targetEntity="Status", inversedBy="docStatus")
     * @ORM\JoinColumn(name="id_status", referencedColumnName="id")
     */
    private $status;


    public function getStatus()
    {
        return $this->status;
    }

    public function getDocument()
    {
        return $this->document;
    }

    /**
     * @var integer
     * @ORM\Id
     * @ORM\Column(name="id_status", type="integer", nullable=false)
     */
    private $idStatus;

    /**
     * Set eventDate
     *
     * @param \DateTime $eventDate
     *
     * @return DocStatus
     */
    public function setEventDate($eventDate)
    {
        $this->eventDate = $eventDate;

        return $this;
    }

    /**
     * Get eventDate
     *
     * @return \DateTime
     */
    public function getEventDate()
    {
        return $this->eventDate;
    }

    /**
     * Set eventDay
     *
     * @param integer $eventDay
     *
     * @return DocStatus
     */
    public function setEventDay($eventDay)
    {
        $this->eventDay = $eventDay;

        return $this;
    }

    /**
     * Get eventDay
     *
     * @return int
     */
    public function getEventDay()
    {
        return $this->eventDay;
    }

    /**
     * Get idDoc
     *
     * @return \Finance\ExpBundle\Entity\Document
     */
    public function getIdDoc()
    {
        return $this->idDoc;
    }

}

For statuses:
Spoiler
<?php

namespace Finance\ExpBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Status
 *
 * @ORM\Table(name="exp_status")
 * @ORM\Entity
 */
class Status
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    private $name;

    /**
     * @var integer
     *
     * @ORM\Column(name="day_by_reglament", type="integer", nullable=false)
     */
    private $dayByReglament = '0';

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;


    /**
     * @ORM\OneToMany(targetEntity="DocStatus", mappedBy="status")
     */
    private $docStatus;


    public function getDocStatus()
    {
        return $this->docStatus;
    }


    /**
     * Set name
     *
     * @param string $name
     *
     * @return Status
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set dayByReglament
     *
     * @param integer $dayByReglament
     *
     * @return Status
     */
    public function setDayByReglament($dayByReglament)
    {
        $this->dayByReglament = $dayByReglament;

        return $this;
    }

    /**
     * Get dayByReglament
     *
     * @return integer
     */
    public function getDayByReglament()
    {
        return $this->dayByReglament;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }
}

As a result, you can get information about the status of a document in Symfony3 in the following way:
In the controller action:
$em = $this->getDoctrine();
$repoDoc = $em->getRepository(Document::class);
$doc = $repoDoc->find($id);

dump($doc->getStatus()->getName());
dump($doc->getStatus()->getDayByReglament());

In the twig template engine:
{{ dump(doc.status.name) }}
{{ dump(doc.status.dayByReglament) }}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question