[英]Embed a Collection of Forms Error: Could not determine access type for property
根據本教程,我正在嘗試將Tag
表單集合嵌入到Service
表單中。 Tag
和Service
實體具有多對多關系。
表單呈現正確。 但是當我提交表單時,我得到
無法確定屬性“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 實現代碼嗎?
首先,請嘗試更改映射/ $service->addTag($this);
,並刪除$service->addTag($this);
來自Tag::addService
方法。
精簡版:
我剛剛遇到了這個問題,並通過為受影響的屬性添加一個 setter 來解決它:
無法確定屬性“tagList”的訪問類型
public function setTagList(Array $tagList)
{
$this->tagList = $tagList;
}
長版:
該錯誤消息表明 Symfony 正在嘗試修改對象的狀態,但由於其類的設置方式,無法弄清楚如何實際進行更改。
看一看 Symfony 的內部結構,我們可以看到 Symfony 給了你 5 次訪問的機會,並按照這個順序從上到下挑選最好的一個:
setProperty()
setter 方法,帶有一個參數:這是 Symfony 檢查的第一件事,也是實現這一目標的最明確的方式。 據我所知,這是最佳做法:
class Entity {
protected $tagList;
//...
public function getTagList()
{
return $this->tagList;
}
//...
}
重要的是要意識到這個方法也將被 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 無法訪問該屬性?
如果您查看拋出異常的位置(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
使用方法addTagList
和removeTagList
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.