[英]Symfony 4 | ManyToMany Relation - Could not determine access type for property
Hello everyone, 大家好,
I am currently working on a project on Symfony 4. I have a ManyToMany relation between two doctrine entities (Groupe and Contact) , however when I"m trying to create a new contact I have the following error: (I emphasize that the entities were created with make: entity). thank you in advance for your help. 我目前正在研究Symfony 4上的一个项目。我在两个学说实体(Groupe和Contact)之间建立了ManyToMany关系,但是当我尝试创建新的联系人时,出现以下错误:(我强调这些实体是使用make:实体创建)。预先感谢您的帮助。
Exceptions : Could not determine access type for property "groupe" in class "App\\Entity\\Contact": The property "groupe" in class "App\\Entity\\Contact" can be defined with the methods "addGroupe()", "removeGroupe()" but the new value must be an array or an instance of \\Traversable, "App\\Entity\\Groupe" given. 例外:无法确定类“ App \\ Entity \\ Contact”中属性“ groupe”的访问类型:可以使用方法“ addGroupe()”,“ removeGroupe”定义类“ App \\ Entity \\ Contact”中的属性“ groupe” ()”,但新值必须是\\ Traversable的数组或实例,并指定了“ App \\ Entity \\ Groupe”。
// Contact.php // 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 // 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 // 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` 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,
]);
}
}
Symfony Forms will use get<Property>
and set<Property>
to read and write the model data. Symfony Forms将使用
get<Property>
和set<Property>
读取和写入模型数据。 In your case, since you don't have a setGroupe()
method on Contact, the form does not know how to write the value back to the entity when you submit the form. 在您的情况下,由于在Contact上没有
setGroupe()
方法,因此在提交表单时表单不知道如何将值写回实体。
For this scenario Symfony Forms have Data Mappers . 对于这种情况,Symfony表单具有数据映射器 。
Data mappers are responsible for reading and writing data from and into parent forms.
数据映射器负责从父表单读取数据和将数据写入父表单。
In your case you will propbably need something like this: 在您的情况下,您可能需要这样的东西:
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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.