Neodark7
Neodark7

Reputation: 23

Symfony / API Platform - Many To Many relationship only working in one way

i'm working on a project where i need to associate "Articles" and "Addresses" entities to an "FAQ" entity. So i wrote those two relations in my Faq entity

/**
 * @ORM\ManyToMany(targetEntity=Article::class, inversedBy="faqs")
 * @Groups({"api_backend"})
 * @MaxDepth(1)
 */
private $article;

/**
 * @ORM\ManyToMany(targetEntity=Adresse::class, inversedBy="faqs")
 * @Groups({"api_backend"})
 * @MaxDepth(1)
 */
private $address;

and add these properties in my Adresse.php

/**
 * @ORM\ManyToMany(targetEntity=Faq::class, mappedBy="address")
 * @Groups({"api_backend"})
 * @MaxDepth(1)
 */
private $faqs;

and Article.php

/**
 * @ORM\ManyToMany(targetEntity=Faq::class, mappedBy="article")
 * @Groups({"api_backend"})
 * @MaxDepth(1)
 */
private $faqs;

When i try to add an article to one of my faqs it works great

Postman Request

[2020-10-27 03:31:50] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-10-27 03:31:50] doctrine.DEBUG: UPDATE faq SET enabled = ? WHERE id = ? [true,3] []
[2020-10-27 03:31:50] doctrine.DEBUG: INSERT INTO faq_article (faq_id, article_id) VALUES (?, ?) [3,352] []
[2020-10-27 03:31:50] doctrine.DEBUG: "COMMIT" [] []

But when i try to add an adress, it's just getting ignored, without any errors

Postman Request

[2020-10-27 03:41:18] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-10-27 03:41:18] doctrine.DEBUG: UPDATE faq SET enabled = ? WHERE id = ? [true,3] []
[2020-10-27 03:41:18] doctrine.DEBUG: "COMMIT" [] []

nothing related to my relationship shows up in the log, and the relation is not updated in the database.

Funny thing, it works great in the other direction, but i can't use that in my application.

Postman Request

[2020-10-27 03:45:07] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-10-27 03:45:08] doctrine.DEBUG: INSERT INTO faq_adresse (faq_id, adresse_id) VALUES (?, ?) [3,16] []
[2020-10-27 03:45:08] doctrine.DEBUG: "COMMIT" [] []

And if i manually add the relationship in the database, i'm able to see it when i get my Faq entity

enter image description here

Any idea anyone ? i'm really getting stuck here

EDIT: I have a legacy easy_admin installed on this project, and everything works great, so i really have something wrong on the api platform side of things.

Upvotes: 1

Views: 4296

Answers (1)

Thamira Madusanka
Thamira Madusanka

Reputation: 129

Address.php

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\AddressRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass=AddressRepository::class)
 */
class Address
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $address1;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $address2;

    /**
     * @ORM\ManyToMany(targetEntity=FAQ::class, mappedBy="addresses")
     */
    private $faqs;

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

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

    public function getAddress1(): ?string
    {
        return $this->address1;
    }

    public function setAddress1(string $address1): self
    {
        $this->address1 = $address1;

        return $this;
    }

    public function getAddress2(): ?string
    {
        return $this->address2;
    }

    public function setAddress2(string $address2): self
    {
        $this->address2 = $address2;

        return $this;
    }

    /**
     * @return Collection|FAQ[]
     */
    public function getFaqs(): Collection
    {
        return $this->faqs;
    }

    public function addFaq(FAQ $faq): self
    {
        if (!$this->faqs->contains($faq)) {
            $this->faqs[] = $faq;
            $faq->addAddress($this);
        }

        return $this;
    }

    public function removeFaq(FAQ $faq): self
    {
        if ($this->faqs->removeElement($faq)) {
            $faq->removeAddress($this);
        }

        return $this;
    }
}

Article.php

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\ArticleRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass=ArticleRepository::class)
 */
class Article
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $description;

    /**
     * @ORM\ManyToMany(targetEntity=FAQ::class, mappedBy="articles")
     */
    private $faqs;

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

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

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    /**
     * @return Collection|FAQ[]
     */
    public function getFaqs(): Collection
    {
        return $this->faqs;
    }

    public function addFaq(FAQ $faq): self
    {
        if (!$this->faqs->contains($faq)) {
            $this->faqs[] = $faq;
            $faq->addArticle($this);
        }

        return $this;
    }

    public function removeFaq(FAQ $faq): self
    {
        if ($this->faqs->removeElement($faq)) {
            $faq->removeArticle($this);
        }

        return $this;
    }
}

FAQ.php

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\FAQRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass=FAQRepository::class)
 */
class FAQ
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $description;

    /**
     * @ORM\ManyToMany(targetEntity=Address::class, inversedBy="faqs")
     */
    private $addresses;

    /**
     * @ORM\ManyToMany(targetEntity=Article::class, inversedBy="faqs")
     */
    private $articles;

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

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

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    /**
     * @return Collection|Address[]
     */
    public function getAddresses(): Collection
    {
        return $this->addresses;
    }

    public function addAddress(Address $address): self
    {
        if (!$this->addresses->contains($address)) {
            $this->addresses[] = $address;
        }

        return $this;
    }

    public function removeAddress(Address $address): self
    {
        $this->addresses->removeElement($address);

        return $this;
    }

    /**
     * @return Collection|Article[]
     */
    public function getArticles(): Collection
    {
        return $this->articles;
    }

    public function addArticle(Article $article): self
    {
        if (!$this->articles->contains($article)) {
            $this->articles[] = $article;
        }

        return $this;
    }

    public function removeArticle(Article $article): self
    {
        $this->articles->removeElement($article);

        return $this;
    }
}

Upvotes: 1

Related Questions