Как можно избежать ошибки сохранения связанных сущностей с помощью cascade в Doctrine в Symfony 5?

Как настроить отношения между сущностями Game, Player и User, чтобы каждая игра имела коллекцию игроков, каждый игрок был связан с объектом пользователя, и у одного пользователя могло быть несколько игроков?
  • 8 февраля 2024 г. 23:39
Ответы на вопрос 2
Для того чтобы настроить отношения между сущностями Game, Player и User в Symfony используя Doctrine, вам необходимо определить эти отношения в соответствующих классах сущностей. Вот пример того, как могли бы выглядеть ваши классы сущностей с соответствующими аннотациями Doctrine:

Сущность Game:

```php
// src/Entity/Game.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @ORM\Entity()
 * @ORM\Table(name="games")
 */
class Game
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Player", mappedBy="game", cascade={"persist", "remove"})
     */
    private $players;

    public function __construct()
    {
        $this->players = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function getPlayers(): Collection
    {
        return $this->players;
    }

    public function addPlayer(Player $player): self
    {
        if (!$this->players->contains($player)) {
            $this->players[] = $player;
            $player->setGame($this);
        }

        return $this;
    }

    public function removePlayer(Player $player): self
    {
        if ($this->players->removeElement($player)) {
            if ($player->getGame() === $this) {
                $player->setGame(null);
            }
        }

        return $this;
    }
}
```

Сущность Player:

```php
// src/Entity/Player.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="players")
 */
class Player
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="players")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Game", inversedBy="players")
     * @ORM\JoinColumn(nullable=false)
     */
    private $game;

    // Other properties and methods

    public function getId()
    {
        return $this->id;
    }

    public function getUser(): ?User
    {
        return $this->user;
    }

    public function setUser(?User $user): self
    {
        $this->user = $user;

        return $this;
    }

    public function getGame(): ?Game
    {
        return $this->game;
    }

    public function setGame(?Game $game): self
    {
        $this->game = $game;

        return $this;
    }
}
```

Сущность User:

```php
// src/Entity/User.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
 * @ORM\Entity()
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Player", mappedBy="user", cascade={"persist", "remove"})
     */
    private $players;

    public function __construct()
    {
        $this->players = new ArrayCollection();
    }

    // Other properties and methods

    public function getId()
    {
        return $this->id;
    }

    public function getPlayers(): Collection
    {
        return $this->players;
    }

    public function addPlayer(Player $player): self
    {
        if (!$this->players->contains($player)) {
            $this->players[] = $player;
            $player->setUser($this);
        }

        return $this;
    }

    public function removePlayer(Player $player): self
    {
        if ($this->players->removeElement($player)) {
            if ($player->getUser() === $this) {
                $player->setUser(null);
            }
        }

        return $this;
    }
}
```

В приведенных выше кодах для класса `Game` мы имеем отношение `OneToMany` к классу `Player`,
Каждому игроку соответствует один объект User - отношение OneToOne, null=false, пользователь обязателен для каждого игрока. У одного пользователя может быть несколько игроков (по каждому игроку на сыгранную игру)

Это не OneToOne, это ManyToOne.
Похожие вопросы