Part # 6 Doctrine One To Many

Handling Doctrine Entity Relations with Symfony

[Back to Learn Symfony 2]

In chapter 5 we've learned how to create a basic entity called Car, now to illistrate a One To Many relationship we are going to create an entity called CarEnergy. A car can be propulsed by diferent kinds of energy: Diesel, Electric, Gasoline,Water,Air....
Let's get hands on it, type on the command line:


php app/console doctrine:generate:entity

The entity short name: MyHelloBundle:CarEnergy
Configuration format: annotation
-- Add some fields here, remember that is not necesary to add any primary or foreign key.
Do you want to generate an empty repository class? yes


Once you are done the class file CarEnergy.php is generated under the Entity folder

namespace My\HelloBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * My\HelloBundle\Entity\CarParts
 *
 * @ORM\Table(name="car_energy")
 * @ORM\Entity(repositoryClass="My\HelloBundle\Entity\CarEnergyRepository")
 */
class CarEnergy
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var text $description
     *
     * @ORM\Column(name="description", type="text")
     */
    private $description;
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set description
     *
     * @param text $description
     */
    public function setDescription($description)
    {
        $this->description = $description;
    }

    /**
     * Get description
     *
     * @return text
     */
    public function getDescription()
    {
        return $this->description;
    }
}

 

Relation One To Many with Symfony 2


Unfortunatelly there no command line to create a One To Many relation, so we are going to define it with annotations inside tne Car.php and the CarEnergy.php class files.

CarEnergy is going to be linked to Car because one Car can have be propulsed by diferrent kinds of energy.

Step 1 Update the Car.php file:

We are going to add one property: energy
   /**
    * @ORM\ManyToOne(targetEntity="CarEnergy", inversedBy="cars")
    * @ORM\JoinColumn(name="energy_id", referencedColumnName="id")
    */
    protected $energy;

  • targetEntity: Name of the entity to be linked
  • inversedBy: Inversed side of the relationship.

The field energy_id will relate the two tables acting as a Foreign Key. The ManyToOne syntax is for the "owner" class, that which have the foreign key field.

Step 2 update the CarEnergy.php file:

We are going to add the property: energy

    /**
* @ORM\OneToMany(targetEntity="Car", mappedBy="energy")
*/
protected $car;

 

Step 3 Create getters and setters from the command line:

php app/console doctrine:generate:entities MyHelloBundle

Step 4 Update database:

Show sql updates

php app/console doctrine:schema:update --dump-sql

Will dump the Sql code into screen.


And now validate the dabase update to create and update tables:

php app/console doctrine:schema:update --force

 

Handling Doctrine Entity Relations with Symfony 2

Lets create the objects and relate them to add new data inside a controller. We are going to add a car parts to our car entity

Open the file DefaultController.php

Add the Entity class

use My\HelloBundle\Entity\CarEnergy;


Create a new action called "test2" to add a car and set its energy type:

 /**
   * @Route("/test2/", name="test2")
   */
    public function test2Action()
    {
        $em = $this->getDoctrine()->getEntityManager();
        $id = 1; // energy id

        $energy = $this->getDoctrine()->getRepository('MyHelloBundle:CarEnergy')->find($id);
        echo " Energy ID: ".$energy->getId()." description: ".$energy->description();

        // Add a new car
        $car = new Car();       
        $car->setModel("Porsche");
        $car->setColor("White");
        $car->setYear("2007");

        $car->setCar($energy); // Link energy type to new car
      
        // Save new car
        $em->persist($car);
        $em->flush();

// Redirect to avoid saving record twice
        return $this->redirect($this->generateUrl('homepage'));
    }

   
Navigate to it to execute action: http://localhost/symfony/test2

Create a new action called "test3" to show OneToMany data

 /**
  * @Route("/test3/", name="test3")
  * @Template()
  */
   public function test3Action()
   {
     $id=1;
$energy = $this->getDoctrine()
->getRepository('MyHelloBundle:CarEnergy')
->find($id);

if (!$energy)
{
throw $this->createNotFoundException('No energy found for id '.$id);
}

return array('energy' => $energy);

    }

Create a template to view data called test3.html.twig

Car List With: {{energy.description}} Energy



 

      {% for item in energy.car %}



    • {{ item.model }}, {{item.color }}, {{item.year }}



      {% else %}



    • No energy



      {% endfor %}

 


Navigate show data: http://localhost/symfony/test3

And you will see:

Car List With: Electric Energy

  • Ford, White, 2010

  • Ferrari, Red, 2007

[Back to Learn Symfony 2]