【问题标题】:Symfony / API Platform - Many To Many relationship only working in one waySymfony / API 平台 - 多对多关系仅以一种方式工作
【发布时间】:2020-10-27 02:48:41
【问题描述】:

我正在做一个项目,我需要将“文章”和“地址”实体与“常见问题解答”实体相关联。所以我在我的常见问题实体中写了这两个关系

/**
 * @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;

并在我的 Adresse.php 中添加这些属性

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

和 Article.php

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

当我尝试将一篇文章添加到我的一个常见问题解答中时效果很好

[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" [] []

但是当我尝试添加地址时,它只是被忽略了,没有任何错误

[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" [] []

日志中没有显示与我的关系相关的任何内容,并且该关系未在数据库中更新。

有趣的是,它在另一个方向上效果很好,但我不能在我的应用程序中使用它。

[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" [] []

如果我在数据库中手动添加关系,我可以在获取我的常见问题实体时看到它

有人知道吗?我真的被困在这里了

编辑:我在这个项目上安装了一个旧的 easy_admin,一切都很好,所以我在 api 平台方面确实有问题。

【问题讨论】:

  • 我不确定,但也许你忘了保留子地址实体?您也可以尝试添加注释 cascade="persist"。无论如何,似乎在调试中回答了您的问题。这种行为的原因太多了。需要查看完整的源代码,或者至少是控制器
  • persist chil 地址实体是什么意思?我试图关联的地址是我数据库中的现有项目。关于级联注释,我应该在哪里添加它?我没有使用任何控制器或规范化器或任何类来扩展 api 平台,您希望查看哪些文件。
  • 编辑:我试图在两个属性上添加 cascade={"persist"} 没有效果:/
  • 对于我的项目,为了让它按照我想要的方向工作,我已经反转了 mappedBy 和 reverseBy

标签: php symfony doctrine many-to-many api-platform.com


【解决方案1】:

地址.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;
    }
}

文章.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;
    }
}

【讨论】:

  • 任何解释都很好,因为我看不出你的答案是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 2016-09-03
  • 1970-01-01
  • 2019-06-17
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多