Skip to content

Instantly share code, notes, and snippets.

@Ocramius
Last active July 24, 2024 14:38
Show Gist options
  • Save Ocramius/3121916 to your computer and use it in GitHub Desktop.
Save Ocramius/3121916 to your computer and use it in GitHub Desktop.
Doctrine 2 ManyToMany - the correct way
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table(name="user")
*/
class User
{
/**
* @var int|null
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer", name="id")
*/
protected $id;
/**
* @var \Doctrine\Common\Collections\Collection|UserGroup[]
*
* @ORM\ManyToMany(targetEntity="UserGroup", inversedBy="users")
* @ORM\JoinTable(
* name="user_usergroup",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="usergroup_id", referencedColumnName="id")
* }
* )
*/
protected $userGroups;
/**
* Default constructor, initializes collections
*/
public function __construct()
{
$this->userGroups = new ArrayCollection();
}
/**
* @param UserGroup $userGroup
*/
public function addUserGroup(UserGroup $userGroup)
{
if ($this->userGroups->contains($userGroup)) {
return;
}
$this->userGroups->add($userGroup);
$userGroup->addUser($this);
}
/**
* @param UserGroup $userGroup
*/
public function removeUserGroup(UserGroup $userGroup)
{
if (!$this->userGroups->contains($userGroup)) {
return;
}
$this->userGroups->removeElement($userGroup);
$userGroup->removeUser($this);
}
}
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table(name="usergroup")
*/
class UserGroup
{
/**
* @var int|null
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer", name="id")
*/
protected $id;
/**
* @var \Doctrine\Common\Collections\Collection|User[]
*
* @ORM\ManyToMany(targetEntity="User", mappedBy="userGroups")
*/
protected $users;
/**
* Default constructor, initializes collections
*/
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* @param User $user
*/
public function addUser(User $user)
{
if ($this->users->contains($user)) {
return;
}
$this->users->add($user);
$user->addUserGroup($this);
}
/**
* @param User $user
*/
public function removeUser(User $user)
{
if (!$this->users->contains($user)) {
return;
}
$this->users->removeElement($user);
$user->removeUserGroup($this);
}
}
@werdck
Copy link

werdck commented Jul 20, 2024

How would you query for a user that is in multiple groups?
eg.
User1 is in Group1 and Group2,
User2 is in Group1,
User3 is in Group2

The query should return only User1.

@haydenk
Copy link

haydenk commented Jul 24, 2024

@werdck I would look into Doctrine specific methods. In that scenario the ORM would load the data for you and groups would be a relationship you can search through the array or collection.

https://www.doctrine-project.org/projects/doctrine-collections/en/stable/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment