ajouter des attributs à une relation Many-To-Many
Pour prévenir les utilisateurs que des messages sont non lus nous devons enregistré l’état pour chaque participant. On va rajouter sur notre relation Many-To-Many l’attribut isRead
Nous avons actuellement ce schéma pour notre base de donnée
Et nous allons rajouter l’attribut is_read
sur discussion_user
comme suit
Actuellement notre relation sur Discussion est définie comme ceci
/**
* @ORM\\ManyToMany(targetEntity=User::class)
* @Groups({"discussion:read", "discussion:write"})
*/
private $participants;
Nous avons besoin de transformer notre relation ManyToMany pour pouvoir lui rajouter des attributs
La table de relation qui à été créée par Doctrine pour lier les participants aux discussions est discussion_user
Nous allons créer une entité Doctrine pour avoir le contrôle sur cette table afin de lui rajouter les attributs
Notez que nous faisons une table de relation sans ajouter d’id qui s’auto incrémente. Nous avons deux ORM\Id
: un pour discussion
et un participant.
Nous avons également indiqué le nom de notre table dans ORM\Table
.
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="discussion_user")
* @ORM\Entity
*/
class DiscussionUser
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="App\Entity\Discussion")
* @ORM\JoinColumn(name="discussion_id", referencedColumnName="id")
*/
private $discussion;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $participant;
/**
* @return mixed
*/
public function getDiscussion()
{
return $this->discussion;
}
/**
* @return mixed
*/
public function getParticipant()
{
return $this->participant;
}
/**
* @param mixed $participant
*/
public function setParticipant($participant): void
{
$this->participant = $participant;
}
/**
* @param mixed $discussion
*/
public function setDiscussion($discussion): void
{
$this->discussion = $discussion;
}
}
On va adapter notre relation côté sur l’entité Discussion
/**
* @ORM\OneToMany(targetEntity=DiscussionUser::class, mappedBy="discussion")
* @Groups({"discussion:read", "discussion:write"})
*/
private $participants;
// ...
/**
* @return Collection|DiscussionUser[]
*/
public function getParticipants(): Collection
{
return $this->participants;
}
public function addParticipant(DiscussionUser $participant): self
{
if (!$this->participants->contains($participant)) {
$this->participants[] = $participant;
}
return $this;
}
public function removeParticipant(DiscussionUser $participant): self
{
$this->participants->removeElement($participant);
return $this;
}
Sur DiscussionUser on indique l'attribut inverse pour discussion
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="App\Entity\Discussion", inversedBy="participants")
* @ORM\JoinColumn(name="discussion_id", referencedColumnName="id")
*/
private $discussion;
Et maintenant on peut rajouter l’attribut qu’on veut sur notre nouvelle entité :
/**
* @ORM\Column(type="boolean", nullable=true)
*/
private $isRead;
// ...
public function getIsRead(): ?bool
{
return $this->isRead;
}
public function setIsRead(?bool $isRead): self
{
$this->isRead = $isRead;
return $this;
}
php bin/console doctrine:schema:update --force
On lance une requête pour mettre tous les messages existant à isRead=true
php bin/console doctrine:query:sql "UPDATE discussion_user SET is_read = true"
Maintenant on défini notre attribut comme étant NON NULL
avec nullable=false
et on mets une valeur par défaut dans le construct
/**
* @ORM\Column(type="boolean", nullable=false)
*/
private $isRead;
public function __construct()
{
$this->isRead = false;
}
On remet à jour notre base de donnée php bin/console doctrine:schema:update --force
Commentaires
Connectez-vous pour laisser un commentaire