Kā īstenot 'has many through' attiecību Doctrine?
sobes.tech AI
Atbilde no AI
Doctrine2 attiecība "has many through" tiek īstenota, izmantojot skaidri izveidotu starpposma entitāti (join entity), kas savieno divas citas entītijas ar Many-to-One attiecībām.
-
Tiek izveidotas trīs entītiju klases: avota, mērķa un starpposma (JoinEntity).
-
Starpposma entitāte (piemēram,
UserGroup"User has many Group through UserGroup") satur divus laukus, kas ir Many-to-One attiecības ar Avota (User) un Mērķa (Group) entītijām. -
Avota un Mērķa entītijas ir One-to-Many attiecībās ar Starpposma entītiju.
-
Lai ērtāk piekļūtu Mērķa entītijām caur Avotu (piemēram, iegūt visas
Grouplietotājam), var pievienot metodi Avota entītijai, kas filtrēs Starpposma entītijas.
Struktūras piemērs:
// User.php
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\OneToMany(targetEntity: UserGroup::class, mappedBy: 'user')]
private Collection $userGroups; // Attiecība ar starpposma entītiju
public function __construct()
{
$this->userGroups = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* Iegūt lietotāja grupas caur starpposma entītiju.
* Tas ir "has many through" ekvivalents.
* Piezīme: atkarībā no vajadzībām, var efektīvi iegūt šo kolekciju.
*/
public function getGroups(): Collection
{
return $this->userGroups->map(fn(UserGroup $userGroup) => $userGroup->getGroup());
}
public function getUserGroups(): Collection
{
return $this->userGroups;
}
public function addUserGroup(UserGroup $userGroup): static
{
if (!$this->userGroups->contains($userGroup)) {
$this->userGroups->add($userGroup);
$userGroup->setUser($this);
}
return $this;
}
public function removeUserGroup(UserGroup $userGroup): static
{
if ($this->userGroups->removeElement($userGroup)) {
if ($userGroup->getUser() === $this) {
$userGroup->setUser(null);
}
}
return $this;
}
}
// Group.php
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Group
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\OneToMany(targetEntity: UserGroup::class, mappedBy: 'group')]
private Collection $userGroups; // Attiecība ar starpposma entītiju
public function __construct()
{
$this->userGroups = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getUserGroups(): Collection
{
return $this->userGroups;
}
public function addUserGroup(UserGroup $userGroup): static
{
if (!$this->userGroups->contains($userGroup)) {
$this->userGroups->add($userGroup);
$userGroup->setGroup($this);
}
return $this;
}
public function removeUserGroup(UserGroup $userGroup): static
{
if ($this->userGroups->removeElement($userGroup)) {
if ($userGroup->getGroup() === $this) {
$userGroup->setGroup(null);
}
}
return $this;
}
}
// UserGroup.php
<?php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'user_user_group')] // Piemēra tabulas nosaukums
class UserGroup
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'userGroups')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null; // Many-to-One uz User
#[ORM\ManyToOne(targetEntity: Group::class, inversedBy: 'userGroups')]
#[ORM\JoinColumn(nullable: false)]
private ?Group $group = null; // Many-to-One uz Group
public function getId(): ?int
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
public function getGroup(): ?Group
{
return $this->group;
}
public function setGroup(?Group $group): static
{
$this->group = $group;
return $this;
}
}
Šis pieeja, lai gan prasa papildus entitātes izveidi, nodrošina pilnīgu kontroli pār saistību datiem un ļauj viegli pievienot papildu laukus starpposma tabulā (piemēram, lietotāja pievienošanas datumu grupai).