Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 get object from inverted entity with ManyToMany relation

I'm facing to a problem with my Doctrine entities relations. Here's the matter :

I have 2 entities : Article and Category Article is the master, category is the slave

I'd like to get Categories from Articles and the other way, Articles from Categories.

I made a ManyToMany relation like this :

class Article
{
    /**
     * @ORM\ManyToMany(targetEntity="Alpha\BlogBundle\Entity\Category", cascade={"persist"}, inversedBy="Article")
     * @ORM\JoinTable(name="article_category")
     */
    private $categories;

and

public function __construct(){
    $this->categories = new \Doctrine\Common\Collections\ArrayCollection();

and the in Category entity :

class Category
{
    /**
     * @ORM\ManyToMany(targetEntity="Alpha\BlogBundle\Entity\Article", cascade={"persist"}, mappedBy="Category")
     */
    private $articles;

and

public function __construct(){
    $this->articles = new \Doctrine\Common\Collections\ArrayCollection();

In my article entity, I also added the folowing :

public function addCategory(\Alpha\BlogBundle\Entity\Category $categories)
{
    $this->categories[] = $categories;
    $categories->addArticle($this);
    return $this;
}

(the forth line, $categories->addArticle($this);)

In my controller :

public function ajouterAction($data = null, $id = null) {

    // On récupère l'EM pour enregistrer en BDD
    $em = $this->getDoctrine()->getManager();

    // On définit une nouvel objet Article avec de nouveaux attributs
    $article = new Article;
    $article->setTitle('1er article !');
    $article->setContent('Cupcake ipsum dolor sit amet ice cream tiramisu unerdwear.com. Caramels halvah lollipop apple pie soufflé. Tart lollipop soufflé candy tootsie roll sweet donut. Lemon drops danish I love icing I love. Candy canes cheesecake I love. I love tiramisu applicake. I love gingerbread soufflé sweet roll muffin. Cupcake liquorice gummi bears muffin chocolate jelly-o.');
    $article->setAuthor('Toto');

    // On définit une nouvel objet Category avec de nouveaux attributs
    $category = new Category;
    $category->setName('Poney');

    $article->addCategory($category);

    $em->persist($category);
    $em->persist($article);

    $em->flush();

    return $this->render('AlphaBlogBundle:Blog:ajouter.html.twig');
}

And to finish, to get my articles from the categories :

public function categoryAction($cat = null) {

    $em = $this->getDoctrine()->getManager();

    // Si cat est vide, on renvoit la liste complète des catégories
    if (!isset($cat) || empty($cat) || $cat == null) {

        $categories = $em->getRepository('AlphaBlogBundle:Category')->findAll();

        return $this->render('AlphaBlogBundle:Blog:categories.html.twig', array(
            'categories' => $categories
        ));
    }
    // Sinon on renvoit la liste des articles de la catégorie
    else {
        $category = $em->getRepository('AlphaBlogBundle:Category')->findOneBy(array('name' => $cat));
        $articles = $category->getArticles();

        return $this->render('AlphaBlogBundle:Blog:category.html.twig', array(
            'articles' => $articles,
            'category' => $category
            //'name' => $name
        ));
    }
}

In my view, I can see the name of my category, but the article is not showing, I have this error message :

ContextErrorException: Notice: Undefined index: Category in /home/franck/www/alpha/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1036

I'm a bit lost here, if someone could help.

like image 359
Neovea Avatar asked Mar 20 '23 01:03

Neovea


2 Answers

As follows from doctrine documentation:

mappedBy: This option specifies the property name on the targetEntity that is the owning side of this relation. Its a required attribute for the inverse side of a relationship.

inversedBy: The inversedBy attribute designates the field in the entity that is the inverse side of the relationship.

So, try to change inversedBy="Article" to inversedBy="articles" in Article class and mappedBy="Category" to mappedBy="categories" in Category class.

Also see this Many-To-Many bidirectional example.

Hope this helps.

like image 126
Revinand Avatar answered Mar 23 '23 11:03

Revinand


All right then, I followed your advice and changed Article with articles, and Category by categories. I also changed my mapping for the master side, Articles, like that :

/**
 * @ORM\ManyToMany(
 *    targetEntity="Alpha\BlogBundle\Entity\Category",
 *    cascade={"persist"},
 *    inversedBy="articles"
 * )
 * @ORM\JoinTable(name="article_category",
 *      joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="id")},
 *      inverseJoinColumns={
 *          @ORM\JoinColumn(name="category_id", referencedColumnName="id")
 *      }
 * )
 */

It works like a charm. I don't exactly understand but I'm gonna study that :)

like image 35
Neovea Avatar answered Mar 23 '23 13:03

Neovea