When you are using Symfony PHP Framework, the most common way to interact with Databases is using Doctrine. And if you are using a relational Database like Oracle, MSSql Server, MySql or MariaDb, you will need to handle Table Associations. One to Many means "One of these can have many of those"

You may refer to this posts:

 

In the Article How to Implement Many to Many Relation in Symfony with Doctrine in easy steps I explained how to easily make the code to handle the Many to Many relation between Animals and Food Entitites.

Now we want to place Many Animals in One Zoo. For doing that we need a One to Many relation.

Step 1. Open up the model we used in the many to many article in MySql Workbench.

Place a new table and name it zoo, then add the primary key and one column. Then Click on the 1:n icon (the 2nd from top to bottom on the relations). The Model should look like this:

 

Step 2. Click on Database > Synchronize Model in the top menu and apply the Sql changes to the schema where you have the animals and food table.

Click on Next until done.

 

Step 3. In a ssh console go to symfony project root directory and import the new mapping.

php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity

UPDATE on May-2023: I just found today that this doctrine:mapping:import that was deprecated a couple of years ago, may not longer work. Please proceed with caution and review carefully the generated Entity files.

 

 At this moment a new Zoo Entity is generated and a new property is added to the Animals one to associate Zoo with Animals:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Animals
 *
 * @ORM\Table(name="animals", indexes={@ORM\Index(name="fk_animals_zoo1_idx", columns={"zoo_id"})})
 * @ORM\Entity
 */
class Animals
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

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

    /**
     * @var \Zoo
     *
     * @ORM\ManyToOne(targetEntity="Zoo")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="zoo_id", referencedColumnName="id")
     * })
     */
    private $zoo;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Food", inversedBy="animals")
     * @ORM\JoinTable(name="animals_has_food",
     *   joinColumns={
     *     @ORM\JoinColumn(name="animals_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="food_id", referencedColumnName="id")
     *   }
     * )
     */
    private $food = array();

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->food = new \Doctrine\Common\Collections\ArrayCollection();
    }

}

Symfony generates the Many To One Association, but if you look at the new Zoo Entity, you'll find that there is no property showing the One To Many Association:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Zoo
 *
 * @ORM\Table(name="zoo")
 * @ORM\Entity
 */
class Zoo
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string|null
     *
     * @ORM\Column(name="zoo_name", type="string", length=45, nullable=true)
     */
    private $zooName;

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

    public function getZooName(): ?string
    {
        return $this->zooName;
    }

    public function setZooName(?string $zooName): self
    {
        $this->zooName = $zooName;

        return $this;
    }


}

You need to create this manually.

Step 4. Add a new property in the Zoo Table and put the following metadata to indicate the One To Many Association:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Zoo
 *
 * @ORM\Table(name="zoo")
 * @ORM\Entity
 */
class Zoo
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string|null
     *
     * @ORM\Column(name="zoo_name", type="string", length=45, nullable=true)
     */
    private $zooName;
    
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Animals", mappedBy="zoo", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
     */
    private $animals;
    

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

    public function getZooName(): ?string
    {
        return $this->zooName;
    }

    public function setZooName(?string $zooName): self
    {
        $this->zooName = $zooName;

        return $this;
    }


}

Now in the console:

php bin/console make:entity --regenerate

If you look at the Zoo Entity, Symfony has added the get, add and remove Animals methods:

<?php

namespace App\Entity;

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

/**
 * Zoo
 *
 * @ORM\Table(name="zoo")
 * @ORM\Entity
 */
class Zoo
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string|null
     *
     * @ORM\Column(name="zoo_name", type="string", length=45, nullable=true)
     */
    private $zooName;
    
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Animals", mappedBy="zoo", cascade={"persist", "refresh", "remove"}, orphanRemoval=true)
     */
    private $animals;

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

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

    public function getZooName(): ?string
    {
        return $this->zooName;
    }

    public function setZooName(?string $zooName): self
    {
        $this->zooName = $zooName;

        return $this;
    }

    /**
     * @return Collection<int, Animals>
     */
    public function getAnimals(): Collection
    {
        return $this->animals;
    }

    public function addAnimal(Animals $animal): self
    {
        if (!$this->animals->contains($animal)) {
            $this->animals->add($animal);
            $animal->setZoo($this);
        }

        return $this;
    }

    public function removeAnimal(Animals $animal): self
    {
        if ($this->animals->removeElement($animal)) {
            // set the owning side to null (unless already changed)
            if ($animal->getZoo() === $this) {
                $animal->setZoo(null);
            }
        }

        return $this;
    }


}

 That's it! you are ready to add Animals to the Zoo.