Relations
Une fois de plus, nous allons utiliser la couche d'abstraction (et la console) pour l'aspect relationnel de notre schéma de base de données
OneToOne
Extrêmement rare (généralement table unique).
Parfois utilisé pour préparer la migration vers un autre type de relation ou pour des questions de performances.
Parfois utilisé pour préparer la migration vers un autre type de relation ou pour des questions de performances.
class Profile { /** * @ORM\OneToOne(targetEntity="App\Entity\Photo", mappedBy="profile", cascade={"persist", "remove"}) */ private $photo; }
ManyToOne
Une ligne est liée à plusieurs lignes dans une autre table.
Exemple : plusieurs héros est lié à un seul héros.
Exemple : plusieurs héros est lié à un seul héros.
class Hero { /** * @ORM\ManyToOne(targetEntity="App\Entity\Profile", inversedBy="heroes") * @ORM\JoinColumn(nullable=false) */ private $profile; }
ManyToMany
Plusieurs lignes sont liées à plusieurs lignes dans une autre table.
On utilise alors une table de jointure (qui a pour clé primaire les éléments de la jointure).
Exemple : le lien entre un héros et des objets (un héros est liée à plusieurs objets, chaque objet est lié à plusieurs héros).
Cette relation peut aussi porter des données complémentaires (ces données seront alors portées par la table de jointure).
On utilise alors une table de jointure (qui a pour clé primaire les éléments de la jointure).
Exemple : le lien entre un héros et des objets (un héros est liée à plusieurs objets, chaque objet est lié à plusieurs héros).
Cette relation peut aussi porter des données complémentaires (ces données seront alors portées par la table de jointure).
class Hero { /** * @ORM\ManyToMany(targetEntity="App\Entity\Item", mappedBy="hero") */ private $items; }
Sens des relations
Les relations que nous avons vues sont unidirectionnelles. Au besoin, il faudra définir leur réciproque.
La classe portant la référence (ici une colonne profile_id dans la
table commentaire) utilisera
inversedBy
. Dans l'autre sens, on utilisera
mappedBy
.
class Hero { /** * @ORM\ManyToOne(targetEntity="App\Entity\Profile", inversedBy="heroes") * @ORM\JoinColumn(nullable=false) */ private $profile; } class Profile { /** * @ORM\OneToMany(targetEntity="App\Entity\Hero", mappedBy="profile", orphanRemoval=true) */ private $heroes; } cla
Il faut noter que par convention, une relation faisant un lien ToMany est appelée au pluriel.
Compléments
Relation facultative
class Profil { /** * @ORM\OneToOne(targetEntity="App\Entity\Photo", mappedBy="profile", cascade={"persist", "remove"}) * @ORM\JoinColumn(nullable=false) */ private $photo; }
Opération Doctrine
Accesseurs
Les accesseurs sont générés par défaut par la console.
/** * @return Collection|Hero[] */ public function getHeroes(): Collection { return $this->heroes; } public function addHero(Hero $hero): self { if (!$this->heroes->contains($hero)) { $this->heroes[] = $hero; $hero->setProfile($this); } return $this; } public function removeHero(Hero $hero): self { if ($this->heroes->contains($hero)) { $this->heroes->removeElement($hero); // set the owning side to null (unless already changed) if ($hero->getProfile() === $this) { $hero->setProfile(null); } } return $this; }
Pour forcer la génération des accesseurs (après une modification manuelle), on peut utiliser :
php bin/console doctrine:generate:entities Profile
Mise à jour du schéma
php bin/console doctrine:schema:update