API Platform 2: many-to-many relation does not persists

197 views Asked by At

I have this situation on a project Im working on, made in Symfony 5 and API Framework 2 (latest 2 version):

  • we have a User entity App\Entity\User
  • now users can be Reps or PAs for other users. Any user can be Rep or PA for n other users

So Ive set a Mant-to-Many self referencing relation, as show in the doctrine documentation:

public function __construct()
{
    $this->userReps = new ArrayCollection();
    $this->userPAs  = new ArrayCollection();
}
/**
 * @ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="userPAs", cascade={"persist", "remove"})
 *
 * @var Collection
 */
private Collection $userReps;

/**
 * @ORM\JoinTable(name="user_rep_user_pa",
 *     joinColumns={@ORM\JoinColumn(name="user_id",referencedColumnName="id", onDelete="CASCADE")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="user_rep_id", referencedColumnName="id", onDelete="CASCADE")}
 *     )
 * @ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="userReps", cascade={"persist", "remove"})
 * @var Collection
 */
private Collection $userPAs;

#[Groups([
    'post',
    'read',
    'write',
    'user:write'
])]
public function getUserReps():array
{
    return $this->userReps->toArray();
}

/**
 * @param User $user
 * @return void
 */
public function addUserRep(User $user):void
{
    $this->userReps->add($user);
}

/**
 * @param User $user
 * @return void
 */
public function removeUserRep(User $user):void
{
    $this->userReps->remove($user);
}

#[Groups([
    'post',
    'read',
    'write',
    'user:write'
])]
public function getUserPAs():array
{
    return $this->userPAs->toArray();
}

/**
 * @param User $user
 * @return void
 */
public function addUserPA(User $user):void
{
    $this->userPAs->add($user);
}

/**
 * @param User $user
 * @return void
 */
public function removeUserPA(User $user):void
{
    $this->userPAs->remove($user);
}

Which seems correct to me.

Ive ran doctrine:migrations:diff/doctrine:migrations:migrate and the user_rep_user_pa table was created on the database. So far so good

Except is not really working: If I try to POST/PUT a user with this on the data:

{
      "userReps": [{
          "id":27
      }]
  }

For example, it saves with no errors, but the relation is not created on user_rep_user_pa

If I try this:

{
    "userReps": [{
        "email": "[email protected]",
        "firstName": "Dummy",
        "lastName": "User",
        "state": "WA"
    }]
}

The new user Dummy is created on User, but still nothing on user_rep_user_pa

If I go into the database and manually create a row on user_rep_user_pa linking the users, API Platform will return it correctly, which seems to indicate its not completely wrong. It just never saves the relation.

What Im doing wrong here? I know Im must be missing something but I just cant find it

edit: I also tried sending:

{
    "userReps": ["1.0.0/users/27"]
}

The result is the same

And in both cases, it will return an error if the id references an user that does not exists.

edit 2:

Still no luck, but I tried a manual test like this:

    $user27 = $userRepository->find(27);
    $user139 = $userRepository->find(139);

    if($user139 && $user27)
    {
        $user139->addUserRep($user27);
        $userRepository->getEntityManager()->persist($user139);
        $userRepository->getEntityManager()->flush();
    }

And still it wont save the relation.

1

There are 1 answers

1
diogo.abdalla On

Ok, I found what I was missing

Changed the above code like this:

public function addUserRep(User $user):void
{
    if(!$user->userPAs->contains($this))
    {
        $user->userPAs->add($this);
    }

    if(!$this->userReps->contains($user))
    {
        $this->userReps->add($user);
    }
}

public function addUserPA(User $user):void
{
    if(!$user->userReps->contains($this))
    {
        $user->userReps->add($this);
    }

    if(!$this->userPAs->contains($user))
    {
        $this->userPAs->add($user);
    }
}

And now it works.

Ill leave it here if anyone needs, not easy to find examples for this