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

Many-To-Many relation

Et nous allons rajouter l’attribut is_read sur discussion_user comme suit

Many-To-Many with extra attributes

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

Many-to-Many transformation to add extra attributes

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