Удаление записи в таблице «многие ко многим» - PullRequest
18 голосов
/ 11 марта 2012

Я следую главе о безопасности книги Symfony 2.

Есть пример с таблицей USERS и GROUPS. Между USERS и GROUPS существует отношение многие-ко-многим , которое создает в базе данных таблицу с именем USERGROUPS.

Я хочу удалить запись из USERGROUPS, например:

DELETE from USERGROUPS WHERE user_id = 1 and group_id = 1 

Я не знаю, как это сделать, поскольку у меня нет USERGROUPS.php табличного файла.

Например, используя DQL, я хочу сделать это:

$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));

Надеюсь, вы поняли идею.

Тогда как мне удалить из этой таблицы?

Ответы [ 2 ]

20 голосов
/ 11 марта 2012

Doctrine рассматривает данные как объекты, а не как строки таблицы. Таким образом, в терминах Doctrine есть объекты Group (которые, среди прочего, содержат пользователей группы) и объекты User (каждый из которых имеет свойство, хранящее группы, в которых находится пользователь). Но нет объектов UserGroup. Идея Doctrine (и любой системы ORM) состоит в том, чтобы позволить разработчику забыть об этих промежуточных таблицах, которые могут понадобиться базе данных, но которые не являются необходимыми с точки зрения объектной модели программы.

Итак, вы хотите загрузить соответствующий объект User, удалить группу из свойства $ groups и сохранить измененный объект User. (Или наоборот, то есть загрузите соответствующий объект Group и удалите из него пользователя.) DQL мог бы справиться с этим, но я думаю, что это проще сделать без DQL, поскольку оператор DELETE DQL предназначен для удаления целых объектов, а не изменяя их свойства.

Попытка:

$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

Примечание: если в вашей модели User нет метода removeGroup () (я думаю, что Symfony может сгенерировать его для вас, но я могу ошибаться), метод может выглядеть следующим образом.

//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);
    }
}
5 голосов
/ 20 июля 2015

В дополнение к ответу @ Ethan, одностороннее удаление не работает.Для таких отношений manyToMany необходимо вызвать методы remove из обеих сущностей, например,

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

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

$em->persist($user);
$em->flush();
...