Symfony 4 | ManyToMany关系-无法确定属性的访问类型

时间:2019-03-03 20:21:53

标签: php symfony doctrine many-to-many

大家好,

我目前正在研究Symfony 4上的一个项目。 我在两个学说实体(Groupe和Contact)之间有一个ManyToMany关系,但是当我尝试创建一个新的联系人时,出现以下错误: (我强调这些实体是使用make:实体创建的)。 预先感谢您的帮助。

例外: 无法确定类“ App \ Entity \ Contact”中属性“ groupe”的访问类型:可以使用方法“ addGroupe()”,“ removeGroupe()”定义类“ App \ Entity \ Contact”中的属性“ groupe” ”,但新值必须是\ Traversable的数组或实例,并指定了“ App \ Entity \ Groupe”。

// Contact.php     

Room: {_id, name}
Row: {_id, roomid, name}
Seat: {_id rowid, position, number, status}

// Groupe.php     

Room.findOne({ name: req.params.room_name }, { __v: 0 })
  .then(room => {
    room = room.toObject();
    Row.find({ room: new ObjectId(room._id) }, { room: 0, __v: 0 })
      .sort({ name: 1 })
      .then(rows => {
        // current code, not working
        // rows.foreach(row => {
        //   row = row.toObject();
        //   Seat.find({row: new OBjectId(row._id)})
        //     .sort({position: 1})
        //     .then(seats => {
        //       row.seats = seats;
        //     })
        //     .catch(err => console.log(err));
        res.json(room);
      })
      .catch(err => console.log(err));
  })
  .catch(err => {
    console.log(err);
    res.status(500).json(err);
  });

// ContactController.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;
   }
}

ContactType.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;
   }

}

1 个答案:

答案 0 :(得分:1)

Symfony表单将使用get<Property>set<Property>读取和写入模型数据。在您的情况下,由于在Contact上没有setGroupe()方法,因此在提交表单时表单不知道如何将值写回实体。

在这种情况下,Symfony表单具有Data Mappers

  

数据映射器负责从父表单读取数据并将数据写入父表单。

在您的情况下,您可能需要这样的东西:

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
}