Search code examples
phpsymfonycollectionsfixturesarraycollection

Could not determine access type for property "games" in class "App\Entity\GameGenre":


I have a Symfony 4.2 application. There are Entities Game and GameGenre. They have ManyToMany relation between each other. I am trying to load fixtures and receive the following error:

Could not determine access type for property "games" in class "App\Entity\GameGenre": The property "games" in class "App\Entity\GameGenre" can be defined with the methods "addGame()", "removeGame()" but the new value must be an array or an instance of \Traversable, "App\Entity\Game" given.

My code is the following.

Game.php

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\GameRepository")
 */
class Game
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

...

    /**
     * @ORM\ManyToMany(
     *     targetEntity="App\Entity\GameGenre",
     *     inversedBy="games"
     * )
     */
    private $genres;

...

    /**
     * @return Collection|GameGenre[]
     */
    public function getGenres() : Collection
    {
        return $this->genres;
    }

    public function addGenre(GameGenre $genre): self
    {
        if (!$this->genres->contains($genre)) {
            $this->genres[] = $genre;
            $genre->addGame($this);
        }

        return $this;
    }

    public function removeGenre(GameGenre $genre): self
    {
        if ($this->genres->contains($genre)) {
            $this->genres->removeElement($genre);
            $genre->removeGame($this);
        }

        return $this;
    }

...

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

GameGenre.php

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\GameGenreRepository")
 */
class GameGenre
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(
     *     targetEntity="App\Entity\Game",
     *     mappedBy="genres"
     * )
     * @ORM\OrderBy({"name" = "ASC"})
     */
    private $games;

...

    /**
     * @return Collection|Game[]
     */
    public function getGames() : Collection
    {
        return $this->games;
    }

    public function addGame(Game $game): self
    {
        if (!$this->games->contains($game)) {
            $this->games[] = $game;
            $game->addGenre($this);
        }

        return $this;
    }

    public function removeGame(Game $game): self
    {
        if ($this->games->contains($game)) {
            $this->games->removeElement($game);
            $game->removeGenre($this);
        }

        return $this;
    }

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

}

And it looks like there is nothing really strange in fixtures yamls:

genre.yaml

App\Entity\GameGenre:
    genre_{1..9}:
...
        games: '@game_*'

game.yaml has no mentioning of genre field but I tried to change relation side by calling addGenre() instead of addGame() or use them both in both fixture files but nothing help, so I think there is some other problem.

Could you please help me?


Solution

  • Your field is an array, but you are trying to insert a single value, it should be:

    App\Entity\GameGenre:
        genre_{1..9}:
    ...
            games: ['@game_*']
    

    or

    App\Entity\GameGenre:
        genre_{1..9}:
    ...
            games:
                - '@game_*'