大家好,
我目前正在做一个关于Symfony 4的项目。我在两个理论实体(Groupe和Contact)之间有一个ManyToMany关系,但是当我试图创建一个新的联系人时,我有以下错误:(我强调实体是用make: entity创建的)。谢谢您的帮助。
异常:无法确定"App\Entity\Contact“类中属性"groupe”的访问类型:可以用"addGroupe()“、"removeGroupe()”方法定义类“App\Entity\Contact”中的属性"groupe“,但新值必须是给定的的数组或实例。
//Contact.php
 namespace App\Entity;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Validator\Constraints as Assert;
 /**
  * @ORM\Entity(repositoryClass="App\Repository\ContactRepository")
  * @ORM\Table(name="cm_f_contact")
  */
 class Contact
 {
  // .....
  /**
   * @ORM\ManyToMany(targetEntity="App\Entity\Groupe", inversedBy="contacts")
   * @Assert\Valid
   */
   private $groupe;
   public function __construct()
   {
     $this->groupe = new ArrayCollection();
   }
   /**
    * @return Collection|Groupe[]
    */
   public function getGroupe(): Collection
   {
     return $this->groupe;
   }
   public function addGroupe(Groupe $groupe): self
   {
     if (!$this->groupe->contains($groupe)) {
        $this->groupe[] = $groupe;
     }
    return $this;
   }
   public function removeGroupe(Groupe $groupe): self
   {
     if ($this->groupe->contains($groupe)) {
        $this->groupe->removeElement($groupe);
     }
    return $this;
   }
}//Groupe.php
  namespace App\Entity;
  use Doctrine\Common\Collections\ArrayCollection;
  use Doctrine\Common\Collections\Collection;
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Validator\Constraints as Assert;
  /**
   * @ORM\Entity(repositoryClass="App\Repository\GroupeRepository")
   * @ORM\Table(name="cm_f_group")
   */
   class Groupe
   {
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Contact", mappedBy="groupe")
     */
    private $contacts;
    public function __construct()
    {
     $this->contacts = new ArrayCollection();
    }
   /**
    * @return Collection|Contact[]
    */
   public function getContacts(): Collection
   {
     return $this->contacts;
   }
   public function addContact(Contact $contact): self
   {
     if (!$this->contacts->contains($contact)) {
        $this->contacts[] = $contact;
        $contact->addGroupe($this);
     }
    return $this;
   }
   public function removeContact(Contact $contact): self
   {
    if ($this->contacts->contains($contact)) {
        $this->contacts->removeElement($contact);
        $contact->removeGroupe($this);
    }
    return $this;
   }
}//ContactController.php
 <?php
  namespace App\Controller;
  use App\Entity\Contact;
  use App\Form\ContactType;
  use App\Repository\ContactRepository;
  use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\HttpFoundation\Response;
  use Symfony\Component\Routing\Annotation\Route;
  /**
   * @Route("/contact")
   */
   class ContactController extends AbstractController
   {
    //...
    /**
     * @Route("/new", name="contact_new", methods={"GET","POST"})
     */
     public function new(Request $request): Response
     {
      $contact = new Contact();
      $form = $this->createForm(ContactType::class, $contact);
      $form->handleRequest($request);
      if ($form->isSubmitted() && $form->isValid()) {    
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($contact);
        $entityManager->flush();
        return $this->redirectToRoute('contact_index');
       }
      return $this->render('contact/new.html.twig', [
        'contact' => $contact,
        'form' => $form->createView(),
      ]);
    }
   }ContactType.php`
    <?php
  namespace App\Form;
  use App\Entity\Contact;
  use App\Entity\Groupe;
  use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Component\OptionsResolver\OptionsResolver;
  class ContactType extends AbstractType
  {
    public function buildForm(FormBuilderInterface $builder, array $options)
     {
      $builder
        ->add('firstname')
        ->add('lastname')
        ->add('email')
        ->add('sms_no')
        ->add('birth_date')
        ->add('created_by')
        ->add('groupes', EntityType::class, [
            'class' => Groupe::class,
            'choice_label' => 'name',
        ])
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Contact::class,
        ]);
    }
}发布于 2019-03-04 06:29:14
Symfony表单将使用get<Property>和set<Property>来读取和写入模型数据。在这种情况下,由于在联系人中没有setGroupe()方法,所以表单在提交表单时不知道如何将值写回实体。
对于这个场景,Symfony表单有数据映射器。
数据映射器负责从父窗体读取和写入数据。
在您的情况下,您可能需要这样的东西:
public function mapFormToData($forms, &$data)
{
    $forms = iterator_to_array($forms);
    // "groupe" is the name of the field in the ContactType form
    $groupe = $forms['groupe'];
    foreach ($groupe as $group) {
        // $data should be a Contact object
        $data->addGroup($group);
    }
    // ...Map remaining form fields to $data
}https://stackoverflow.com/questions/54973362
复制相似问题