私はSymfony2の本のセキュリティの章をフォローしています。
テーブル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));
私はあなたがその考えを理解することを望みます。
次に、このテーブルから削除するにはどうすればよいですか?
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);
}
}
@Ethanの回答に加えて、一方向の削除は機能していません。このようなmanyToMany
関係の場合、たとえば、両方のエンティティからremove
メソッドを呼び出す必要があります。
$user = $em->findOneById($userId);
$group = $em->findOneById($groupId);
$user->removeGroup($group);
$group->removeUser($user);
$em->persist($user);
$em->flush();