【问题标题】:How to administer Doctrine ORM Class Table Inheritance via SonataAdminBundle (Symfony)?如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?
【发布时间】: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 实体。

我的问题是:如何才能在管理区域的BarOneBarTwo 之间切换?也就是说,这样我就可以实现 Doctrine ORM(类表继承)提供的多项选择。

【问题讨论】:

    标签: symfony doctrine-orm sonata-admin sonata


    【解决方案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”。有什么解决办法吗?
    猜你喜欢
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多