문제

Suppose we have a field with ManyToMany relation as

/**
* @var ArrayCollection
* 
* @ORM\ManyToMany(targetEntity="Users")
* @ORM\JoinTable(name="users_roles",
*      joinColumns={@ORM\JoinColumn(name="User_Id", referencedColumnName="id")},
*      inverseJoinColumns={@ORM\JoinColumn(name="Role_Id", referencedColumnName="id")})
*/
protected $userRole;

To remove one related element from table we can have this function in our entity:

/**
* Remove userRole
* @param \Acme\MyBundle\Entity\Users $user
*/
public function remvoveUserRole(\Acme\MyBundle\Entity\Users $user)
{
    $this->userRole->removeElement($user);
}

The Question:

The ArrayCollection type has the function removeElement which is used to remove one element of the relationship. There is another function clear which in api says Clears the collection, removing all elements, therefore can I have a function like below in my entity to clear all the related elements so that by flushing it removes all?

/**
* Remove all user Roles
*/
public function remvoveAllUserRole()
{
    $this->userRole->clear();
}

will it work for just ManyToMany related tables or it might work for ManyToOne, too?

도움이 되었습니까?

해결책 2

Note: This logic works for ManyToMany relationship, but not for ManyToOne

I tested the way to delete all related roles for specific use (ManyToMany) and it worked. What you need is to define a function in your UserEntity as

/**
* Remove all user Roles
*/
public function remvoveAllUserRole()
{
   $this->userRole->clear();
}

Then in your controller or anywhere else(if you need) you can call the function as below

$specificUser = $em->getRepository('MyBundle:Users')->findOneBy(array('username' => 'test user'));
if (!empty($specificUser)) {
   $specificUser->removeAllUserRole();
   $em->flush();
}

Then it will delete all related roles for the test user and we don't need to use the for loop and remove them one by one

다른 팁

Ţîgan Ion is right - removeElement/clear only removes those elements from memory.

However, I think you could achieve something as close depending on how did you configure cascade and orphanRemoval in your relationship.

$em = ...; // your EntityManager
$roles = $user->getRoles();
$roles->clear();
$user = $em->merge($user); // this is crucial
$em->flush();

In order for this to work, you need to configure User relationship to

  • cascade={"merge"} - this will make $em->merge() call propagate to roles.
  • orphanRemoval = true - since this is @ManyToMany, this will make EntityManager remove free-dangling roles.

Can't test this now, but as far as I can see it could work. I will try this out tomorrow and update the answer in need be.

Hope this helps...

if I'm not mistaken, this will not work, you have to delete the "role s" from the arrayCollection directly from the database

$roles = $user->getRoles()
foreach $role from $roles 
           $em->remove($role);
$em->flush();

now you should get an empty collection

p.s: the best way is to test your ideas

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top