Search code examples
phpsymfonydoctrine-ormsymfony1

Recursive entity Doctrine


I want to make a navbar in my web site.

I've a SQL table Menu. A menu can have child menu, etc ....

CREATE TABLE IF NOT EXISTS MENU
(
    menu_Id INT AUTO_INCREMENT NOT NULL,
    nom VARCHAR(100) NOT NULL,
    route VARCHAR(255) NOT NULL,
    parent INT NULL,
    CONSTRAINT pk_MENU PRIMARY KEY (menu_Id),
    CONSTRAINT fk_MENU_MENU FOREIGN KEY (parent) REFERENCES MENU(menu_Id)
);

And I've a class in my symfony project in Entity folder.

namespace AppBundle\Entity;

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

/**
 * @ORM\Entity
 * @ORM\Table(name="menu")
 */
class Menu
{
    /**
     * @ORM\Column(name="menu_Id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(name="nom", type="string", length=100)
     */
    protected $lib;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $route;

    /**
     * @ORM\OneToMany(targetEntity="Menu", mappedBy="parent")
     */
    protected $listeSousMenus;

    //... GETTERS AND SETTERS ...
}

When I display the page, I've this error :

An exception has been thrown during the rendering of a template ("Notice: Undefined index: parent") in bandeau.html.twig at line 23.

How can I solve the error ? How can I implement my menu with recursive childs ?


Solution

  • The error is explicite : where is your parent field?

    You need to add a parent property:

    /**
    * @ORM\ManyToOne(targetEntity="Menu", inversedBy="listeSousMenus")
    * @ORM\JoinColumn(name="parent", referencedColumnName="menu_Id")
    */
    protected $parent;
    

    Look this example in documentation: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-self-referencing

    <?php
    /** @Entity */
    class Category
    {
        // ...
        /**
         * @OneToMany(targetEntity="Category", mappedBy="parent")
         */
        private $children;
    
        /**
         * @ManyToOne(targetEntity="Category", inversedBy="children")
         * @JoinColumn(name="parent_id", referencedColumnName="id")
         */
        private $parent;
        // ...
    
        public function __construct() {
            $this->children = new \Doctrine\Common\Collections\ArrayCollection();
        }
    }