如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?
Posted
技术标签:
【中文标题】如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?【英文标题】:How to administer Doctrine ORM Class Table Inheritance via SonataAdminBundle (Symfony)? 【发布时间】:2017-12-05 09:37:21 【问题描述】:我有一个 Doctrine-entity Foo
通过一对一模型与 AbstractBar
Doctrine-entity 相关。
/**
* @ORM\Table(name="foo")
* @ORM\Entity
*/
class Foo
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var AbstractBar
*
* @ORM\OneToOne(targetEntity="AbstractBar", cascade="persist")
* @ORM\JoinColumn(name="bar_id", referencedColumnName="id")
*/
private $bar;
AbstractBar
实体是一个抽象实体,两个特定实体使用 Class Table Inheritance 关联起来
所以,我有这个:
/**
* @ORM\Table(name="bar")
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="bar_type", type="string")
* @ORM\DiscriminatorMap("one" = "BarOne", "two" = "BarTwo")
*/
abstract class AbstractBar
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Table(name="bar_one")
* @ORM\Entity
*/
class BarOne extends AbstractBar
// BarOne class properties
/**
* @ORM\Table(name="bar_two")
* @ORM\Entity
*/
class BarTwo extends AbstractBar
// BarTwo class properties
Foo
实体的管理面板(SonataAdminBundle)配置如下:
class FooAdmin extends AbstractAdmin
protected function configureFormFields(FormMapper $formMapper)
$formMapper
->add('bar', AdminType::class, array(), array(
'admin_code' => 'key.of.bar_one.admin.service'
))
;
同时,管理员类服务配置如下:
key.of.bar_one.admin.service:
class: MyBundle\Admin\BarAdmin
arguments: [~, MyBundle\Entity\BarOne, ~]
tags:
- name: sonata.admin
manager_type: orm
show_in_dashboard: false
上面的代码允许我通过编辑 Foo 实体来编辑和创建 BarOne 实体。
我的问题是:如何才能在管理区域的BarOne
和BarTwo
之间切换?也就是说,这样我就可以实现 Doctrine ORM(类表继承)提供的多项选择。
【问题讨论】:
【参考方案1】:为您的抽象 AbstractBar
类创建一个管理类,例如
# MyBundle/Admin/BarAdmin.php
class BarAdmin extends AbstractAdmin
...
并为其定义服务,使用setSubclasses
调用来定义您的表/对象继承:
key.of.bar.admin.service:
class: MyBundle\Admin\AbstractBarAdmin
arguments: [~, MyBundle\Entity\AbstractBar, SonataAdminBundle:CRUD]
tags:
- name: sonata.admin, manager_type: orm, show_in_dashboard: false
calls:
- [setSubclasses, ['Bar One': MyBundle\Entity\BarOne, 'Bar Tow': MyBundle\Entity\BarTwo]]
更新您的FooAdmin
以使用新创建的管理类:
$formMapper
->add('bar', AdminType::class, array(), array(
'admin_code' => 'key.of.bar.admin.service'
))
;
在BarAdmin
类中,您可以检查必须相应调整管理员的具体对象,例如配置表单域时
/**
* @param FormMapper $form
*/
protected function configureFormFields( FormMapper $form )
$subject = $this->getSubject();
// add shared fields
$form->add();
// BarOne fields
if ( $subject instanceof BarOne )
// BarTwo fields
if ( $subject instanceof BarTwo )
【讨论】:
感谢您的回答,很好地描述并与文档保持一致。但是,当我创建一个新的“Foo”时,它给了我一个错误:无法初始化抽象类:“MyBundle\Entity\AbstractBar”。有什么解决办法吗?以上是关于如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?的主要内容,如果未能解决你的问题,请参考以下文章
将自己的操作添加到 SonataAdminBundle 下拉菜单
SonataAdminBundle configureFormFields 与两步相关实体
如何在 SonataAdminBundle 的上传字段上方显示当前图片?