Munkhdelger Tumenbayar
Munkhdelger Tumenbayar

Reputation: 1884

how to use form builder to make form from entity relation of entity in symfony4

TL;TR:How to make form fields from formbuilder with relation column

Here is my Level Entity

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\LevelRepository")
 */
class Level
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Area", mappedBy="levelid", orphanRemoval=true)
     */
    private $areas;

    public function __construct()
    {
        $this->areas = 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;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;

        return $this;
    }

    /**
     * @return Collection|Area[]
     */
    public function getAreas(): Collection
    {
        return $this->areas;
    }

    public function addArea(Area $area): self
    {
        if (!$this->areas->contains($area)) {
            $this->areas[] = $area;
            $area->setLevelid($this);
        }

        return $this;
    }

    public function removeArea(Area $area): self
    {
        if ($this->areas->contains($area)) {
            $this->areas->removeElement($area);
            // set the owning side to null (unless already changed)
            if ($area->getLevelid() === $this) {
                $area->setLevelid(null);
            }
        }

        return $this;
    }
}

and this is my Area Entity

<?php

namespace App\Entity;

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

/**
 * @ORM\Entity(repositoryClass="App\Repository\AreaRepository")
 */
class Area
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Property", mappedBy="area")
     */
    private $property;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Level", inversedBy="areas")
     * @ORM\JoinColumn(nullable=false)
     */
    private $levelid;

    public function __construct()
    {
        $this->property = new ArrayCollection();
        $this->projects = 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|property[]
     */
    public function getProperty(): Collection
    {
        return $this->property;
    }

    public function addProperty(property $property): self
    {
        if (!$this->property->contains($property)) {
            $this->property[] = $property;
            $property->setArea($this);
        }

        return $this;
    }

    public function removeProperty(property $property): self
    {
        if ($this->property->contains($property)) {
            $this->property->removeElement($property);
            // set the owning side to null (unless already changed)
            if ($property->getArea() === $this) {
                $property->setArea(null);
            }
        }

        return $this;
    }

    public function getLevelid(): ?Level
    {
        return $this->levelid;
    }

    public function setLevelid(?Level $levelid): self
    {
        $this->levelid = $levelid;

        return $this;
    }

   }

Area connected to Level

And this is Area Form builder

<?php

namespace App\Form;

use App\Entity\Area;
// use App\Entity\District;
use App\Entity\Level;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

class AreaType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('Level', EntityType::class, array(
                // looks for choices from this entity
                'class' => Level::class,
                'label' => 'Level',
                // uses the User.username property as the visible option string
                'choice_label' => 'name',
            ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Area::class,
        ]);
    }
}

And the error is

Neither the property "Level" nor one of the methods "getLevel()", "level()", "isLevel()", "hasLevel()", "__get()" exist and have public access in class "App\Entity\Area".

Upvotes: 0

Views: 673

Answers (1)

Ion Bazan
Ion Bazan

Reputation: 838

Your problem is caused by form field and Entity field name mismatch. AreaType tries to refer to level property using Symfony's PropertyAccessor on Area while it does not have such field.

You should either rename your entity field from $levelid to $level (because it actually holds an Entity, not ID), changing setter and getter accordingly (recommended solution) or change form field name from Level to levelid.

You can find more information about Symfony Forms in official docummentation.

Upvotes: 2

Related Questions