如何在不删除 Sonata AdminBundle 中的实体的情况下分离关系?

Posted

技术标签:

【中文标题】如何在不删除 Sonata AdminBundle 中的实体的情况下分离关系?【英文标题】:How detach relation without deleting entity in Sonata AdminBundle? 【发布时间】:2018-02-19 11:44:03 【问题描述】:

我有两个实体:专业化和课程。 一个专业有很多课程,所以关系是“OneToMany”和“ManyToOne”。

我想分别创建专业和课程,然后通过多项选择将许多课程附加到专业。 而且我还需要从专业中删除(分离)课程,但不删除课程实体。 所以,我是这样做的:

->add('courses', 'sonata_type_model', [
                        'multiple' => true,
                        'property' => 'title',
                    ])

但是当我从专业编辑页面的选择字段中删除相关课程时,课程对象也会从数据库中删除。 我试图从关系中删除 orphanRemoval 属性,但是当我尝试从专业中分离课程时,没有任何反应。

所以,我的问题是: 如何在 SonataAdminBundle 中仅实现子实体与父实体的分离?

【问题讨论】:

能否请您发布您的实体定义,一个课程也可以出现在多个专业中吗? 【参考方案1】:

我解决了!

解决方案: 我决定使用保存挂钩(我的 SpecialisationAdmin 类中的方法 prePersist 和 preUpdate)。

主要思想 - 从专业化中取消设置所有相关课程,然后设置来自表单的那些。

但是,如果我在编辑页面上从专业化中删除任何课程,我不会在 preUpdate 方法的专业化对象中获取它们的对象。 如果我没有得到课程对象,我不能将他们的专业设置为 NULL。

所以,这个问题的解决方法是使用snapshot属性获取所有提交表单前的专业化课程,并将其专业化设置为NULL,然后将当前专业化设置为来自表单的课程:

    /**
     * @param Specialisation $specialisation
     */
    public function prePersist($specialisation)
    
        $this->preUpdate($specialisation);
    

    /**
     * @param Specialisation $specialisation
     */
    public function preUpdate($specialisation)
    
        if (isset($specialisation->getCourses()->snapshot)) 
            foreach ($specialisation->getCourses()->getSnapshot() as $course) 
                $course->setSpecialisation(null);
            
        
        foreach ($specialisation->getCourses() as $course) 
            $course->setSpecialisation($specialisation);
        
    

【讨论】:

以上是关于如何在不删除 Sonata AdminBundle 中的实体的情况下分离关系?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - Sonata adminbundle 菜单不会显示

奏鸣曲 缺少论点

FOS 用户更新错误

Symfony Sonata Admin 仅将属性显示为只读文本

编辑奏鸣曲用户数据

sonata_type_model_list 选择后如何删除图像