web-dev-qa-db-ja.com

多対多テーブルのレコードを削除する

私はSymfony2の本のセキュリティの章をフォローしています。

テーブルUSERSGROUPSの例があります。 USERSGROUPSの間には多対多の関係があり、データベースに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));

私はあなたがその考えを理解することを望みます。

次に、このテーブルから削除するにはどうすればよいですか?

18
Francisco Ochoa

Doctrineは、データをテーブルの行ではなくオブジェクトとして考えます。したがって、Doctrineの用語では、Groupオブジェクト(特にグループのユーザーを保持する)とUserオブジェクト(それぞれにユーザーがいるグループを格納するプロパティがあります)があります。しかし、UserGroupオブジェクトはありません。Doctrine(および任意のORMシステム)のアイデアは、データベースが必要とする可能性があるが必要ではないこれらの中間テーブルを開発者に忘れさせることです。プログラムのオブジェクトモデルの観点から。

したがって、必要なのは、関連するUserオブジェクトをロードし、その$ groupsプロパティからグループを削除して、変更されたUserオブジェクトを永続化することです。 (またはその逆、つまり、関連するグループオブジェクトをロードし、そこからユーザーを削除します。)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

注:ユーザーモデルに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);
    }
}
20
Ethan

@Ethanの回答に加えて、一方向の削除は機能していません。このようなmanyToMany関係の場合、たとえば、両方のエンティティからremoveメソッドを呼び出す必要があります。

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

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

$em->persist($user);
$em->flush();
5
Sithu