Search code examples
doctrine-ormentityentitymanager

Doctrine2 - How to remove ManyToMany associations on add of new ones


I've took a quick look but can't find the answer.

Take the following entities, users who can have many roles:

/**
* @Entity
**/

class User 
{

    /**
    * @ManyToMany(targetEntity="Role", inversedBy="users")
    * @JoinTable(name="user_to_roles")
    **/ 
    protected $roles;

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

    public function addRole(Role $role)
    {
        $role->addUser($this);
        $this->roles[] = $role;
    }

    public function getRoles()
    {
        return $this->roles;
    }
}

and the roles:

/**
* @Entity
**/

class Role
{
    /**
    * @Id
    * @Column(type="integer")
    * @GeneratedValue(strategy="AUTO")
    **/
    protected $id;

    /**
    * @ManyToMany(targetEntity="User", mappedBy="roles")
    **/
    protected $users;

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

    public function addUser(User $user)
    {
        $this->users[] = $user;
    }

    public function getUsers()
    {
        return $this->users;
    }
}

When I want to update a user I will get the reference, and update like so:

$user = $this>entityManager->getReference('App\Entity\User', $id);
$user->addRole($role);
$this->entityManager->persist($user);
$this->entityManager->flush();

However, this will continuously add new roles to my relational table, whereas I just want to update the current row, or delete it and create a new one (whichever is easier). How can I achieve this?


Solution

  • Try to add this function to your entity:

    function setRoles($roles) {
      $this->roles = new ArrayCollection($roles);
    }
    

    And when you update try this:

    $user = $this>entityManager->getReference('App\Entity\User', $id);
    $roles = array();
    
    // add your roles to the array roles
    
    $user->setRoles($roles);    
    $this->entityManager->persist($user);
    $this->entityManager->flush();