Sonata Admin 自引用关系错误
Sonata Admin Self Referencing relation Error
如果我在管理员中启用父字段,我会收到一个奇怪的错误:当前字段 parent
未链接到管理员。请为目标实体创建一个:``
这是我有问题的 MenuItem 实体:
namespace App\Entity;
use App\Util\TranslationUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="cms_menu_items")
*/
class MenuItem {
public function __construct() {
$this->children = new ArrayCollection();
}
/**
* @ORM\Id
* @ORM\Column(type="string")
* @ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
/**
* @return string
*/
public function getId(): string { return $this->id ?: '' ; }
// more fields ...
/**
* @var array|ArrayCollection
* @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
*/
protected $children = [];
public function getChildren(): Collection { return $this->children; }
/**
* Add email
*
* @param MenuItem $child
* @return MenuItem
*/
public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }
/**
* Remove MenuItem
*
* @param MenuItem $child
* @return MenuItem
*/
public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }
/**
* Many Categories have One Category.
* @ORM\Column(nullable=true)
* @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
protected $parent;
public function getParent(): ?MenuItem { return $this->parent; }
public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }
/**
* @ORM\ManyToOne(targetEntity="Page")
* @ORM\JoinColumn(name="page", referencedColumnName="id")
*/
protected $page;
public function getPage() : ?Page { return $this->page; }
public function setPage($page) : MenuItem { $this->page = $page; return $this; }
}
还有管理员 Class,工作一尘不染,除非我启用父字段:
<?php
namespace App\Admin;
use App\Entity\MenuItem;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class MenuItemAdmin extends AbstractAdmin {
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('ident', TextType::class, ['required' => false])
->add('label', TextareaType::class, [
'attr' => ['rows' => 6]
])
->add('page', ModelAutocompleteType::class, [
'required' => true,
'property' => ['title', 'id']
])
// this field below is throwing the above mentioned error
->add('parent', ModelAutocompleteType::class, [
'required' => false,
'property' => ['ident', 'label']
])
;
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper) {
$datagridMapper
->add('id')
->add('ident')
->add('label')
;
}
protected function configureListFields(ListMapper $listMapper) {
$listMapper
->addIdentifier('id')
->add('ident')
->add('label')
->add('page')
->add('parent')
;
}
}
如果能帮助我指明正确的方向,我们将不胜感激。非常感谢!
看来我在 Doctrine ORM 数据库注释中犯了一个错误,因此 Sonata Admin 无法正确 link 该字段。
最终我尝试了 运行 bin/console doctrine:schema:validate
并得到了以下错误:
[FAIL] The entity-class App\Entity\MenuItem mapping is invalid:
* The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which is not defined as association, but as field.
* The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which does not exist.
在我将自引用 OneToMany 关系的菜单项注释更改为以下代码后,效果非常好:)
class MenuItem {
// [...] same as above
/**
* @var array|ArrayCollection
* @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
*/
protected $children = [];
public function getChildren(): Collection { return $this->children; }
/**
* Add email
*
* @param MenuItem $child
* @return MenuItem
*/
public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }
/**
* Remove MenuItem
*
* @param MenuItem $child
* @return MenuItem
*/
public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }
/**
* Many Categories have One Category.
* @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
*/
protected $parent;
public function getParent() : ?MenuItem { return $this->parent; }
public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }
}
如果我在管理员中启用父字段,我会收到一个奇怪的错误:当前字段 parent
未链接到管理员。请为目标实体创建一个:``
这是我有问题的 MenuItem 实体:
namespace App\Entity;
use App\Util\TranslationUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="cms_menu_items")
*/
class MenuItem {
public function __construct() {
$this->children = new ArrayCollection();
}
/**
* @ORM\Id
* @ORM\Column(type="string")
* @ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
/**
* @return string
*/
public function getId(): string { return $this->id ?: '' ; }
// more fields ...
/**
* @var array|ArrayCollection
* @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
*/
protected $children = [];
public function getChildren(): Collection { return $this->children; }
/**
* Add email
*
* @param MenuItem $child
* @return MenuItem
*/
public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }
/**
* Remove MenuItem
*
* @param MenuItem $child
* @return MenuItem
*/
public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }
/**
* Many Categories have One Category.
* @ORM\Column(nullable=true)
* @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
protected $parent;
public function getParent(): ?MenuItem { return $this->parent; }
public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }
/**
* @ORM\ManyToOne(targetEntity="Page")
* @ORM\JoinColumn(name="page", referencedColumnName="id")
*/
protected $page;
public function getPage() : ?Page { return $this->page; }
public function setPage($page) : MenuItem { $this->page = $page; return $this; }
}
还有管理员 Class,工作一尘不染,除非我启用父字段:
<?php
namespace App\Admin;
use App\Entity\MenuItem;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class MenuItemAdmin extends AbstractAdmin {
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('ident', TextType::class, ['required' => false])
->add('label', TextareaType::class, [
'attr' => ['rows' => 6]
])
->add('page', ModelAutocompleteType::class, [
'required' => true,
'property' => ['title', 'id']
])
// this field below is throwing the above mentioned error
->add('parent', ModelAutocompleteType::class, [
'required' => false,
'property' => ['ident', 'label']
])
;
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper) {
$datagridMapper
->add('id')
->add('ident')
->add('label')
;
}
protected function configureListFields(ListMapper $listMapper) {
$listMapper
->addIdentifier('id')
->add('ident')
->add('label')
->add('page')
->add('parent')
;
}
}
如果能帮助我指明正确的方向,我们将不胜感激。非常感谢!
看来我在 Doctrine ORM 数据库注释中犯了一个错误,因此 Sonata Admin 无法正确 link 该字段。
最终我尝试了 运行 bin/console doctrine:schema:validate
并得到了以下错误:
[FAIL] The entity-class App\Entity\MenuItem mapping is invalid:
* The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which is not defined as association, but as field.
* The association App\Entity\MenuItem#children refers to the owning side field App\Entity\MenuItem#parent which does not exist.
在我将自引用 OneToMany 关系的菜单项注释更改为以下代码后,效果非常好:)
class MenuItem {
// [...] same as above
/**
* @var array|ArrayCollection
* @ORM\OneToMany(targetEntity="MenuItem", mappedBy="parent")
*/
protected $children = [];
public function getChildren(): Collection { return $this->children; }
/**
* Add email
*
* @param MenuItem $child
* @return MenuItem
*/
public function addChildren(MenuItem $child) {$this->children[] = $child; return $this; }
/**
* Remove MenuItem
*
* @param MenuItem $child
* @return MenuItem
*/
public function removeChildren(MenuItem $child) { $this->children->removeElement($child); return $this; }
/**
* Many Categories have One Category.
* @ORM\ManyToOne(targetEntity="MenuItem", inversedBy="children")
*/
protected $parent;
public function getParent() : ?MenuItem { return $this->parent; }
public function setParent($parent) : MenuItem { $this->parent = $parent; return $this; }
}