Grechka Vassili
Grechka Vassili

Reputation: 883

Error on ManyToMany association

I'm trying to add a new manager from admin to my application but I'm having this error :

The property "nurseries" in class "VS\CrmBundle\Entity\Staff" can be defined with the methods "addNurseries()", "removeNurseries()" but the new value must be an array or an instance of \Traversable, "VS\CrmBundle\Entity\Nursery" given.

I have a ManyToMany association between Nursery and Staff classes :

class Staff extends User
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Nursery", inversedBy="staff", cascade={"persist"})
     * @ORM\JoinTable(name="nursery_staff",
     *     joinColumns={@ORM\JoinColumn(name="staff_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="nursery_id", referencedColumnName="id")}
     *  )
     */
    private $nurseries;

    /**
     * Staff constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->nurseries = new ArrayCollection();
    }
    /**
     * @param Nursery $nursery
     */
    public function addNurseries(Nursery $nursery)
    {
        $nursery->addStaff($this);
        $this->nurseries[] = $nursery;
    }

    /**
     * @param Nursery $nursery
     */
    public function removeNurseries(Nursery $nursery)
    {
        $this->nurseries->removeElement($nursery);
    }

    /**
     * @return ArrayCollection
     */
    public function getNurseries()
    {
        return $this->nurseries;
    }

And :

class Nursery
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Staff", mappedBy="nurseries", cascade={"persist"})
     * @ORM\JoinTable(name="nursery_staff")
     */
    private $staff;
    /**
     * Nursery constructor.
     */
    public function __construct()
    {
        $this->staff = new ArrayCollection();
        $this->schedule = new ArrayCollection();
        $this->createdAt = new \DateTime();
        $this->contacts = new ArrayCollection();
        $this->registerRecord = new ArrayCollection();
    }
    /**
     * Add staff
     *
     * @param \VS\CrmBundle\Entity\Staff $staff
     *
     * @return Nursery
     */
    public function addStaff(\VS\CrmBundle\Entity\Staff $staff)
    {
        $this->staff[] = $staff;

        return $this;
    }

    /**
     * Remove staff
     *
     * @param \VS\CrmBundle\Entity\Staff $staff
     */
    public function removeStaff(\VS\CrmBundle\Entity\Staff $staff)
    {
        $this->staff->removeElement($staff);
    }

    /**
     * Get staff
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getStaff()
    {
        return $this->staff;
    }

Then I have this controller :

   public function addAction(Request $request)
    {
        //Create the forms
        $manager = new Staff();
        $managerForm = $this->get('form.factory')->create(StaffFromAdminType::class, $manager);

        $managerForm->handleRequest($request);
        if($managerForm->isSubmitted() && $managerForm->isValid())
        {
            $manager->setStaffRole('MANAGER');

            $em = $this->getDoctrine()->getManager();
            $em->persist($manager);
            $em->flush();

            $this->addFlash('success', 'The Manager has been successfully added.');

            return $this->redirectToRoute('vs_crm_admin_dashboard');
        }

        return $this->render("VSCrmBundle:Admin/Manager:add-manager.html.twig", array(
            'manager_form' => $managerForm->createView()
        ));
    }

and finally this is my form :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('firstName')
        ->add('lastName')
        ->add('email')
        ->add('addresses', CollectionType::class, array(
            'entry_type' =>  AddressType::class,
            'allow_add' => true
        ))
        /*
        ->add('medias', CollectionType::class, array(
            'entry_type' => MediaType::class,
            'allow_add' => true
        ))*/
        ->add('staffRole')
        ->add('nurseries', EntityType::class, array(
            'class' => 'VSCrmBundle:Nursery',
        ));
}

and this log :

[1] Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException: The property "nurseries" in class "VS\CrmBundle\Entity\Staff" can be defined with the methods "addNurseries()", "removeNurseries()" but the new value must be an array or an instance of \Traversable, "VS\CrmBundle\Entity\Nursery" given.
    at n/a
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 614

    at Symfony\Component\PropertyAccess\PropertyAccessor->writeProperty(array(object(Staff), object(Staff)), 'nurseries', object(Nursery))
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 202

    at Symfony\Component\PropertyAccess\PropertyAccessor->setValue(object(Staff), object(PropertyPath), object(Nursery))
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php line 93

    at Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator), object(Staff))
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 618

    at Symfony\Component\Form\Form->submit(array('nurseries' => '1', 'firstName' => 'Jacques', 'lastName' => 'Dupont', 'email' => '[email protected]', '_token' => 'tULa-SoBQArpx34h9d5gNOi93t2gXw_ZSlsdc52Fvus'), true)
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler.php line 113

    at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest(object(Form), object(Request))
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 488

    at Symfony\Component\Form\Form->handleRequest(object(Request))
        in C:\wamp64\www\app\src\VS\CrmBundle\Controller\ManagerController.php line 36

    at VS\CrmBundle\Controller\ManagerController->addAction(object(Request))
        in  line 

    at call_user_func_array(array(object(ManagerController), 'addAction'), array(object(Request)))
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php line 153

    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), '1')
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php line 68

    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), '1', true)
        in C:\wamp64\www\app\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php line 169

    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in C:\wamp64\www\app\web\app_dev.php line 28

So I just want the admin to choose the right nursery in a list of all the registered nurseries, add some data for the new manager and save the manager with with the link between the new manager and an existing nursery.

Upvotes: 0

Views: 508

Answers (1)

Gopal Joshi
Gopal Joshi

Reputation: 2358

You are generating elemtment of Object nursery in form. Instead you need to pass array of nursery. Try after adding 'multiple' => true in FormType.

FormType

->add('nurseries', EntityType::class, array(
     'multiple' => true,     
     'class' => 'VSCrmBundle:Nursery'
))

Note: 'multiple' => true will create array type control instead of object.

Upvotes: 2

Related Questions