2017-02-15 21 views
18

我試圖根據this tutorialTag表單的集合嵌入到Service表單中。 TagService實體之間有多對多的關係。嵌入表單集合錯誤:無法確定屬性的訪問類型

窗體呈現正確。但是當我提交表格時,我收到

Could not determine access type for property "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; 
} 
} 

Tag類

{ 
    /** 
* @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; 
} 
} 

ServiceController的

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(), 
    )); 
} 
+0

http://stackoverflow.com/questions/41213014/could-not-determine-access -type-for-property-file – craigh

+0

這裏是產生錯誤的失敗測試,​​也許理解它會有所幫助:https://github.com/symfony/property-access/blob/master/Tests/PropertyAccessorCollectionTest.php#L151 – craigh

+0

@craigh如果我做了'mapped => false',我將無法編輯'tagList',因爲它會寫入,但不會讀取值 – blahblah

回答

2

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

如果你看到了該異常被拋出(在PropertyAccessor接口類寫屬性的方法),它說,它可以被拋出:

If the property does not exist or is not public.

在你提到它具有屬性$標記,方法addTag教程。我只是猜測在這裏,但也許有一個公約,它試圖調用方法名稱add($singularForm),這是失敗的,因爲屬性是tagList和方法是addTag

我不是100%確定的,但您可以嘗試通過在Symfony方法中設置一個停止點來查看它爲什麼被拋出。

1

也許你忘記了Service類和Tag類的__construct()來初始化$ tagList和$ serviceList這樣?

$this->tagList = new ArrayCollection();

$this->serviceList = new ArrayCollection();

+0

Hello!不,我沒有忘記在類構造函數中初始化標記和服務列表 – blahblah

1

這似乎是與你的構造一個錯誤。試試這個:

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

Hello!不,我沒有忘記將類構造函數中的標記和服務列表初始化爲ArrayCollection() – blahblah

1

這是一個長鏡頭,但看着你的註釋我認爲這個問題可能與你的manyToMany關係有關。嘗試改變擁有方和反方(交換關係),除非你特別需要從兩端進行更新(在這種情況下,我認爲唯一的解決方案是手動添加對象或使用oneToMany關係)。

Changes made only to the inverse side of an association are ignored. Make sure to update both sides of a bidirectional association (or at least the owning side, from Doctrine’s point of view)

這是關係到原則問題我以前都出現了,請看: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

2

短版:

我只是碰到了這個問題,並通過添加一個設置器解決了它受影響物業:

Could not determine access type for property "tagList"

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

龍版本:

錯誤消息信令的Symfony試圖修改對象的狀態,但無法弄清楚如何真正做出改變,由於其類設置方式。

Taking a look at Symfony's internals,我們可以看到,Symfony的給你5個機會,給它訪問,並挑選最好的順序從上到下:

  1. 有一個說法叫setProperty()的setter方法:

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

class Entity { 

    protected $tagList; 

    //... 

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

    //... 
} 
  • 組合getter和setter的一個方法用一個參數:
  • 很重要意識到這個方法也會被Symfony訪問,以便得到這個對象的狀態。由於這些方法調用不包含參數,因此此方法中的參數必須是可選的。

    class Entity { 
    
        protected $tagList; 
    
        //... 
    
        public function tagList($tags = null) 
        { 
         if($reps){ 
          $this->tagList = $tags; 
         } else { 
          return $this->tagList; 
         } 
        } 
    
        //... 
    } 
    
  • 受影響的屬性被聲明爲公共的:

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

  • 這會影響所有屬性而不僅僅是你想要的那個。

    class Entity { 
    
        public $tagList; 
    
        //... 
    
        public function __set($name, $value){ 
         $this->$name = $value; 
        } 
        //... 
    } 
    
  • __call魔術方法(在一些情況下):
  • 我無法確認這一點,但內部代碼表明這是可能的時在PropertyAccessor的構建中啓用了magic


    只需要使用上述策略之一。基於Symfony的3.3.10

    0

    我真的面臨這個問題很多,很多次,最後一次我發現哪裏這個問題來自何處,取決於你給你的實體屬性它可能發生的名稱加法器卸妝爲您的收藏屬性不完全是你所期望的。

    例:你的實體properity名稱爲「foo」和你所期望的加法器被稱爲「addFoo」和卸妝「removeFoo」,但隨後突然的「無法確定財產的訪問類型」出現。

    於是你開始進入恐懼搜索代碼中的瓦特/電子的問題,而是你必須要看看裏面Symfony的核心文件,此文件:

    供應商/ symfony中/ symfony中/ src目錄/ Symfony的/分量/ PropertyAccess/PropertyAccessor.php

    在這個文件裏面有一個叫做的方法findAdderAndRemover。 用你的調試器去那裏,你最終會發現symfony爲你的加法器/去除器搜索奇怪的名字,它們可能實際上以「um」或「on」或「us」結尾,這取決於語言(人類語言)你曾經爲它們命名。由於我是意大利人,這經常發生。

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

    這發生在我身上時,我使用斌/控制檯學說:生成:實體創建方法自動爲我

    相關問題