Doctrine - One-To-Many Relationship

Asked

Viewed 777 times

1

Good afternoon!

I’m in a relationship with Doctrine and I have a question. I have 2 tables in my database, the Log table and the Log details, where 1 log can contain multiple records referenced to it in the Log Details table. I would like to do the One-To-Many relationship between these tables, but I still have a doubt about that.

I understood the issue of Doctrine Annotations, where I will do the mooring between the entities and references between the key fields, but I could not understand how do I store a list of objects of log details inside the log.

I do not know if I could be clear in my explanation.

1 answer

1


Suppose you have a table Log and a LogDetalhe. First of all you will create the entities that will be mapped to the corresponding tables:

Table Log:

<?php

namespace AppBundle\Entity;

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

/**
 * @ORM\Entity
 */
class Log
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="LogDetalhe", mappedBy="log")
     */
    protected $logDetalhes;

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

    public function getLogDetalhes()
    {
        return $this->logDetalhes;
    }

    public function addLogDetalhe(LogDetalhe $logDetalhe)
    {
        $this->logDetalhes->add($logDetalhe);

        return $this;
    }

    public function removeLogDetalhe(LogDetalhe $logDetalhe)
    {
        $this->logDetalhes->remove($logDetalhe);

        return $this;
    }
}

Table LogDetalhe:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class LogDetalhe
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Log", inversedBy="logDetalhes")
     * @ORM\JoinColumn(nullable=false)
     */
    protected $log;

    public function getLog()
    {
        return $this->log;
    }

    public function setLog(Log $log)
    {
        $this->log = $log;

        return $this;
    }
}

Note that the relationship is bidirectional because not only do I wish to pick up the details from the log, as I wish to pick up the log from a specific detail.

Then, to create a log and its corresponding details, just do as follows:

$log = new Log();
$this->manager->persist($log);

$logDetalhe1 = (new LogDetalhes())->setLog($log);
$this->manager->persist($logDetalhe1);

$logDetalhe2 = (new LogDetalhes())->setLog($log);
$this->manager->persist($logDetalhe2);

$logDetalhe3 = (new LogDetalhes())->setLog($log);
$this->manager->persist($logDetalhe3);

$this->manager->flush();

See that first the Log was created, and then I connected several entities of the type LogDetalhe to the first. Each of these entities shall be continued by EntityManager of Doctrine, to be saved in the bank by the method flush().

  • What if I wanted to make a one-way relationship? How should I proceed in this case? When searching for a log that has more than one registered detail have some form of Doctrine automatically popular the objects?

  • In this case you remove the property you no longer need and also the attributes mappedBy and inversedBy on each side. Since you wouldn’t pick up the details directly through the model, you can use the methods of EntityRepository to get a log and its details using a DQL (Doctrine Query Language).

  • Sorry my ignorance friend, I don’t know if that’s what you tried to explain to me, but I would like to maintain a one-way relationship between the tables, where through the log I can access your details, and within the log object store an array with the details of the log in question. I would also like to know how to perform a method where popularized the log object and with its proper nested details.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.