2012-03-11 11 views
17

Estoy siguiendo el capítulo de seguridad del libro de Symfony 2. Hay un ejemplo con una tabla USERS y GROUPS. Hay una relación many-to-many entre USERS y GROUPS, que crea en la base de datos una tabla llamada USERGROUPS.Eliminación de registros en la tabla de muchos a muchos

Lo que yo quiero es eliminar un registro de USERGROUPS, por ejemplo:

DELETE from USERGROUPS WHERE user_id = 1 and group_id = 1 

No sé cómo hacer esto, ya que no tengo un archivo USERGROUPS.php mesa.

Usando DQL, por ejemplo, yo quiero ser capaz de hacer esto:

$em = $this->getDoctrine()->getEntityManager(); 
$query = $em->createQuery(
    'DELETE FROM AcmeStoreBundle:UserGroups ug WHERE ug.user_id = :user 
    and ug.group_id = :group' 
)->setParameter(array('user' => $userid, 'group' => $groupid)); 

espero se entiende la idea.

Entonces, ¿cómo elimino de esta tabla?

Respuesta

17

Doctrine piensa en los datos como objetos, en lugar de como filas de tabla. Entonces, en términos de Doctrine, hay objetos de grupo (que retienen a los usuarios del grupo, entre otras cosas) y hay objetos de usuario (cada uno de los cuales tiene una propiedad que almacena los grupos en los que se encuentra el usuario). Pero no hay objetos UserGroup. La idea de Doctrine (y cualquier sistema ORM) es permitir que el desarrollador se olvide de estas tablas intermedias que la base de datos podría necesitar, pero que no son necesarias en términos del modelo de objetos del programa.

Lo que quiere hacer es cargar el objeto Usuario correspondiente, eliminar el grupo de su propiedad $ groups y conservar el objeto User modificado. (O viceversa, es decir, cargue el objeto de grupo relevante y elimine el usuario de él). DQL podría ser capaz de manejar esto, pero creo que es más fácil hacerlo sin DQL ya que la declaración DELETE de DQL es para eliminar objetos enteros, no modificando sus propiedades.

Probar:

$user = $em->find('User', $userId); 
$user->removeGroup($groupId); //make sure the removeGroup method is defined in your User model. 
$em->persist($user); 
$em->flush(); //only call this after you've made all your data modifications 

Nota: si usted no tiene un método removeGroup() en su modelo de usuario (creo Symfony puede generar una para ti, pero puedo estar equivocado), el método podría mira como sigue.

//In User.php, and assuming the User's groups are stored in $this->groups, 
//and $groups is initialized to an empty ArrayCollection in the User class's constructor 
//(which Symfony should do by default). 

class User 
{ 
    //all your other methods 

    public function removeGroup($group) 
    { 
     //optionally add a check here to see that $group exists before removing it. 
     return $this->groups->removeElement($group); 
    } 
} 
+0

Ethan. ¡Muchas gracias! Funcionó :) ¿Por qué Symfony no generó este método automáticamente? Creo que es una tarea realmente común eliminar algo de la tabla de muchos a muchos. –

+0

Sí, siempre me he preguntado por qué Symfony tampoco genera métodos de eliminación (ya que genera addMethods). Me alegro de que funcionó! – Ethan

+3

¿Qué sucede si hay 1,000,000 de registros en la tabla de muchos a muchos relacionados con este usuario y necesito eliminar solo uno? Doctrine cargará todos los registros? –

4

Además de la respuesta de @ Ethan, la eliminación unidireccional no funciona. Para tales manyToMany relación, usted tiene que llamar a los métodos remove de ambas entidades, por ejemplo,

$user = $em->findOneById($userId); 
$group = $em->findOneById($groupId); 

$user->removeGroup($group); 
$group->removeUser($user); 

$em->persist($user); 
$em->flush(); 
+0

¿Su solución es equivalente a Eliminar de la tabla donde col1 = y col2 = ? ¿Hace la pregunta en la tabla unida? – Volatil3

+0

Parece ser así – Sithu

Cuestiones relacionadas