簡體   English   中英

嵌入表單集合錯誤:無法確定屬性的訪問類型

[英]Embed a Collection of Forms Error: Could not determine access type for property

根據本教程,我正在嘗試將Tag表單集合嵌入到Service表單中。 TagService實體具有多對多關系。

表單呈現正確。 但是當我提交表單時,我得到

無法確定屬性“tagList”的訪問類型

錯誤。 我不明白為什么沒有通過調用addTag()方法將新的Tag對象添加到Service類中。

服務類型

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', TextType::class, array(
            'label' => 'Title'
        ))
    ;

    $builder->add('tagList', CollectionType::class, array(
        'entry_type' => TagType::class,
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => false
    )));
}

服務類

{
....
 /**
 * @ORM\ManyToMany(targetEntity="Tag", mappedBy="serviceList",cascade={"persist"})
 */ 
private $tagList;

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

/**
 * @param Tag $tag
 * @return Service
 */
public function addTag(Tag $tag)
{
    if ($this->tagList->contains($tag) == false) {
        $this->tagList->add($tag);
        $tag->addService($this);
    }
}

/**
 * @param Tag $tag
 * @return Service
 */
public function removeTag(Tag $tag)
{
    if ($this->tagList->contains($tag)) {
        $this->tagList->removeElement($tag);
        $tag->removeService($this);
    }
    return $this;
}
}

標簽類

 {
  /**
 * @ORM\ManyToMany(targetEntity="Service", inversedBy="tagList")
 * @ORM\JoinTable(name="tags_services")
 */
private $serviceList;
 /**
 * @param Service $service
 * @return Tag
 */
public function addService(Service $service)
{
    if ($this->serviceList->contains($service) == false) {
        $this->serviceList->add($service);
        $service->addTag($this);
    }
    return $this;
}

/**
 * @param Service $service
 * @return Tag
 */
public function removeService(Service $service)
{
    if ($this->serviceList->contains($service)) {
        $this->serviceList->removeElement($service);
        $service->removeTag($this);
    }
    return $this;
}
 }

服務控制器

  public function newAction(Request $request)
{
    $service = new Service();
    $form = $this->createForm('AppBundle\Form\ServiceType', $service);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

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

        return $this->redirectToRoute('service_show', array('id' => $service->getId()));
    }

    return $this->render('AppBundle:Service:new.html.twig', array(
        'service' => $service,
        'form' => $form->createView(),
    ));
}

你能嘗試從這個 URL 實現代碼嗎?

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#owning-and-inverse-side-on-a-manytomany-association

首先,請嘗試更改映射/ $service->addTag($this); ,並刪除$service->addTag($this); 來自Tag::addService方法。

精簡版:

我剛剛遇到了這個問題,並通過為受影響的屬性添加一個 setter 來解決它:

無法確定屬性“tagList”的訪問類型

public function setTagList(Array $tagList)
{
    $this->tagList = $tagList;
}

長版:

該錯誤消息表明 Symfony 正在嘗試修改對象的狀態,但由於其類的設置方式,無法弄清楚如何實際進行更改。

看一看 Symfony 的內部結構,我們可以看到 Symfony 給了你 5 次訪問的機會,並按照這個順序從上到下挑選最好的一個:

  1. 一個名為setProperty() setter 方法,帶有一個參數:

這是 Symfony 檢查的第一件事,也是實現這一目標的最明確的方式。 據我所知,這是最佳做法:

class Entity {

    protected $tagList;

    //...

    public function getTagList()
    {
        return $this->tagList;
    }

    //...
}
  1. 一個方法中的組合 getter 和 setter,帶有一個參數:

重要的是要意識到這個方法也將被 Symfony 訪問以獲取對象的狀態。 由於這些方法調用不包含參數,因此此方法中的參數必須是可選的。

class Entity {

    protected $tagList;

    //...

    public function tagList($tags = null)
    {
        if($reps){
            $this->tagList = $tags;
        } else {
            return $this->tagList;
        }
    }

    //...
}
  1. 受影響的財產被宣布為公共:

     class Entity { public $tagList; //... other properties here }
  2. __set魔法方法:

這將影響所有屬性,而不僅僅是您想要的屬性。

class Entity {

    public $tagList;

    //...

    public function __set($name, $value){
        $this->$name = $value;
    }
    //...
}
  1. __call魔術方法(在某些情況下):

我無法確認這一點,但內部代碼表明,當在 PropertyAccessor 的構造上啟用magic時,這是可能的。


只需要使用上述策略之一。

也許問題是 Symfony 無法訪問該屬性?

如果您查看拋出異常的位置(PropertyAccessor 類中的 writeProperty 方法),它會說它可以拋出:

如果該屬性不存在或不公開。

在您提到的教程中,它具有屬性 $tags 和方法 addTag。 我只是在這里猜測,但也許有一個約定,它嘗試調用方法名稱add($singularForm)並且這對您來說失敗了,因為屬性是tagList而方法是addTag

我不是 100% 確定,但是您可以通過在該 Symfony 方法中設置停止點來嘗試調試,以查看它被拋出的原因。

也許您忘記在 Service 類和 Tag 類的__construct()中像這樣初始化 $tagList 和 $serviceList ?

$this->tagList = new ArrayCollection();

$this->serviceList = new ArrayCollection();

這似乎是您的構造函數的錯誤。 嘗試這個 :

public function __construct()
{
    $this-> tagList = new \Doctrine\Common\Collections\ArrayCollection();
}

這是一個遠景,但查看您的注釋,我認為問題可能與您的多對多關系有關。 嘗試更改擁有方和反向方(交換關系),除非您特別需要從兩端更新(在這種情況下,我認為唯一的解決方案是手動添加對象或使用 oneToMany 關系)。

僅對關聯的反面所做的更改將被忽略。 確保更新雙向關聯的雙方(或至少是擁有方,從 Doctrine 的角度來看)

這是我之前遇到的與 Doctrine 相關的問題,請參閱: http : //docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

基於 Symfony 3.3.10

我實際上多次遇到過這個問題,最后,一旦我發現了這個問題的來源,根據您給實體屬性的名稱,可能會發生您的集合屬性的加法器移除與您不完全相同正在期待。

示例:您的實體屬性名稱是“foo”,並且您希望加法器被稱為“addFoo”,移除器被稱為“removeFoo”,但是突然出現“無法確定屬性的訪問類型”

所以你開始害怕在你的代碼中搜索 w/e 問題,而你只需要在 Symfony 核心文件中查看這個文件:

供應商/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php

在這個文件中有一個叫做findAdderAndRemover的方法。 和你的調試器一起去那里,你最終會發現 symfony 為你的加法器/去除器搜索奇怪的名字,它們實際上可能以“嗯”或“開”或“我們”結尾,這取決於你曾經使用的語言(人類語言)命名它們。 因為我是意大利人,這種情況經常發生。

請注意這一點,因為修復可能就像更改實體中用於添加/刪除方法的名稱一樣簡單,以使它們與 Symfony 核心正在尋找的內容相匹配。

當我使用bin/console 原則:生成:實體為我自動創建方法時,這發生在我身上

如果您正在使用 symfony,並使用 EntityRepository 而不是 CollectionType,請確保在您的表單構建中使用'multiple' => true, ,否則輸入將用於一個實體而不是多個實體,因此它將調用setTagList使用方法addTagListremoveTagList

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM