首页 > 解决方案 > Symfony ManyToMany setter 返回错误数据

问题描述

我有用户与优惠券多对多的关系。用户有很多优惠券,优惠券可能属于许多用户。当我调用 $coupon->getUsers() 方法时,我得到了优惠券 (PersistentCollection)。当我调用 $user->getCoupon() 方法时,我得到了用户 (PersistentCollection)。

用户实体:

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Coupon", inversedBy="users")
     */
    private $coupon;

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

    /**
     * @return Collection|Coupon[]
     */
    public function getCoupon(): Collection
    {
        return $this->coupon;
    }

    public function addCoupon(Coupon $coupon): self
    {
        if (!$this->coupon->contains($coupon)) {
            $this->coupon[] = $coupon;
        }

        return $this;
    }

    public function removeCoupon(Coupon $coupon): self
    {
        if ($this->coupon->contains($coupon)) {
            $this->coupon->removeElement($coupon);
        }

        return $this;
    }

优惠券实体:

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="coupon")
     */
    private $users;

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

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->addCoupon($this);
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->users->contains($user)) {
            $this->users->removeElement($user);
            $user->removeCoupon($this);
        }

        return $this;
    }

当我运行此代码时:

namespace App\Controller;

use App\Entity\Coupon;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class TestController extends AbstractController
{
    /**
     * @Route("/test", name="test")
     */
    public function index()
    {
        $coupon = $this->getDoctrine()->getRepository(Coupon::class)->find(1);

        dump($coupon->getUsers());die;
    }
}

我得到: 截图

为什么我得到的是优惠券而不是用户列表?

标签: phpsymfonydoctrinemany-to-many

解决方案


除了 Jakumi 写的,在控制器中你还可以做

$coupon = $this->getDoctrine()->getRepository(Coupon::class)->find(1);

$users = $coupon->getUsers();
$users->initialize();

现在当你dump($users)的集合不应该是空的。

除此之外,我相信您的映射错误。在您的多对多关系User中,拥有方Coupon是反面,但它是public function addUser(User $user)Coupon实体中完成拥有方的工作。您应该更改侧面(将mappedByin更改CouponinversedBy和 中的其他方式User)或确保这样User做:

public function addCoupon(Coupon $coupon): self
{
    if (!$this->coupon->contains($coupon)) {
        $coupon->addUser($this);
        $this->coupon[] = $coupon;
    }

    return $this;
}

并且Coupon确实:

public function addUser(User $user): self
{
    if (!$this->users->contains($user)) {
        $this->users[] = $user;
    }

    return $this;
}

当然removeUserremoveCoupon方法应该相应地处理。


推荐阅读