Akku
Akku

Reputation: 41

Easyadmin manyToMany relation not saving data in base

I have a ManyToMany relation between my ressource and my categories. But when i'm trying to create a new ressource with easyadmin, the choosed categories are not saved in database. Do you have any ideas?

Here is my ressource class


namespace App\Entity;

use App\Repository\RessourceRepository;
use App\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=RessourceRepository::class)
 */
class Ressource
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="text")
     */
    private $content;

    /**
     * @ORM\Column(type="string", length=500)
     */
    private $summary;

    /**
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $illustration;

    /**
     * @ORM\ManyToOne(targetEntity=User::class, inversedBy="ressources")
     * @ORM\JoinColumn(nullable=false)
     */
    private $creator;

    /**
     * @ORM\OneToMany(targetEntity=Favorite::class, mappedBy="ressources")
     */
    private $favorites;

    /**
     * @ORM\ManyToOne(targetEntity=RelationType::class, inversedBy="ressources")
     * @ORM\JoinColumn(nullable=false)
     */
    private $relation_type;

    /**
     * @ORM\ManyToOne(targetEntity=RessourceType::class, inversedBy="ressources")
     * @ORM\JoinColumn(nullable=false)
     */
    private $RessourceType;

    /**
     * @ORM\ManyToMany(targetEntity=Category::class, mappedBy="ressource")
     */
    private $categories;

    /**
     * @ORM\OneToMany(targetEntity=Comment::class, mappedBy="ressource")
     */
    private $comments;

    /**
     * @ORM\ManyToOne(targetEntity=Status::class, inversedBy="ressource")
     * @ORM\JoinColumn(nullable=false)
     */
    private $status;

    /**
     * @ORM\Column(type="boolean", options={"default":false})
     */
    private $isPublished;

    public function __construct()
    {
        $this->favorites = new ArrayCollection();
        $this->categories = new ArrayCollection();
        $this->comments = new ArrayCollection();
        $this->createdAt = new \DateTime();
    }

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

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getSummary(): ?string
    {
        return $this->summary;
    }

    public function setSummary(string $summary): self
    {
        $this->summary = $summary;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    public function getIllustration(): ?string
    {
        return $this->illustration;
    }

    public function setIllustration(string $illustration): self
    {
        $this->illustration = $illustration;

        return $this;
    }

    public function getCreator(): ?User
    {
        return $this->creator;
    }

    public function setCreator(?User $creator): self
    {
        $this->creator = $creator;

        return $this;
    }

    /**
     * @return Collection|Favorite[]
     */
    public function getFavorites(): Collection
    {
        return $this->favorites;
    }

    public function addFavorite(Favorite $favorite): self
    {
        if (!$this->favorites->contains($favorite)) {
            $this->favorites[] = $favorite;
            $favorite->setRessources($this);
        }

        return $this;
    }

    public function removeFavorite(Favorite $favorite): self
    {
        if ($this->favorites->removeElement($favorite)) {
            // set the owning side to null (unless already changed)
            if ($favorite->getRessources() === $this) {
                $favorite->setRessources(null);
            }
        }

        return $this;
    }

    public function getRelationType(): ?RelationType
    {
        return $this->relation_type;
    }

    public function setRelationType(?RelationType $relation_type): self
    {
        $this->relation_type = $relation_type;

        return $this;
    }

    public function getRessourceType(): ?RessourceType
    {
        return $this->RessourceType;
    }

    public function setRessourceType(?RessourceType $RessourceType): self
    {
        $this->RessourceType = $RessourceType;

        return $this;
    }

    /**
     * @return Collection|Category[]
     */
    public function getCategories(): Collection
    {
        return $this->categories;
    }

    public function addCategory(Category $category): self
    {
        if (!$this->categories->contains($category)) {
            $this->categories[] = $category;
            $category->addRessource($this);
        }

        return $this;
    }

    public function removeCategory(Category $category): self
    {
        if ($this->categories->removeElement($category)) {
            $category->removeRessource($this);
        }

        return $this;
    }

    /**
     * @return Collection|Comment[]
     */
    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function addComment(Comment $comment): self
    {
        if (!$this->comments->contains($comment)) {
            $this->comments[] = $comment;
            $comment->setRessource($this);
        }

        return $this;
    }

    public function removeComment(Comment $comment): self
    {
        if ($this->comments->removeElement($comment)) {
            // set the owning side to null (unless already changed)
            if ($comment->getRessource() === $this) {
                $comment->setRessource(null);
            }
        }

        return $this;
    }

    public function getStatus(): ?Status
    {
        return $this->status;
    }

    public function setStatus(?Status $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getIsPublished(): ?bool
    {
        return $this->isPublished;
    }

    public function setIsPublished(bool $isPublished): self
    {
        $this->isPublished = $isPublished;

        return $this;
    }
}

My category class


namespace App\Entity;

use App\Repository\CategoryRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=CategoryRepository::class)
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity=Ressource::class, inversedBy="categories")
     */
    private $ressource;

    public function __toString()
    {
        return $this->name;
    }


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

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return Collection|Ressource[]
     */
    public function getRessource(): Collection
    {
        return $this->ressource;
    }

    public function addRessource(Ressource $ressource): self
    {
        if (!$this->ressource->contains($ressource)) {
            $this->ressource[] = $ressource;
        }

        return $this;
    }

    public function removeRessource(Ressource $ressource): self
    {
        $this->ressource->removeElement($ressource);

        return $this;
    }
}

The ressourceCrudController for easy admin


namespace App\Controller\Admin;

use App\Entity\Ressource;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;


class RessourceCrudController extends AbstractCrudController
{
    public static function getEntityFqcn(): string
    {
        return Ressource::class;
    }


    public function configureFields(string $pageName): iterable
    {
        return [
            TextField::new('title', 'Titre'),
            TextField::new('summary', 'Résumé'),
            TextareaField::new('content', 'Contenu'),
            DateTimeField::new('createdAt', 'Date et heure de création'),
            ImageField::new('illustration', 'Image')
                ->setBasePath('uploads/')
                ->setUploadDir('public/uploads/')
                ->setUploadedFileNamePattern('[randomhash].[extension]')
                ->setRequired(false),
            AssociationField::new('creator', 'Créer par'),
            AssociationField::new('RessourceType', 'Type de ressource'),
            AssociationField::new('categories', 'Catégorie'),
            AssociationField::new('relation_type'),
            AssociationField::new('status'),
            BooleanField::new('isPublished'),

        ];
    }

}

When i'm completing the form to create a new ressource, i can select the categories, but after the validation, i have 0 in the categories column instead of the ones I chose. I dont have any idea about what is happening and i've find nothing on the internet. Thank you in advance for any tips, clues

Upvotes: 4

Views: 3395

Answers (1)

Select0r
Select0r

Reputation: 12638

Had the same problem, this symfonycast explains the reason why it's not working (it's not a bug): https://symfonycasts.com/screencast/collections/saving-inverse-side-collection

The described necessary changes are probably already included (they are if you use symfony 5), except one thing: I was only looking for a solution for ManyToMany (and couldn't find it), but the problem also occurs with other relations, so I found this post: Symfony 5 easyadmin 3 Entity with relation ManyToOne - NOT saving on the "many" side

So basically you just have to add ->setFormTypeOption('by_reference', false) in the controller of the "mappedBy"-side.

Upvotes: 7

Related Questions