duan0530 2014-01-29 01:29
浏览 46
已采纳

实体的父ID不会保存在SonataAdmin的OneToMany关系中

I'm using SonataAdmin (and Symfony2) to manage my entities. I have a oneToMany relationship between one Step and many Tasks. Since one Step can contain many Tasks, when I create a Step, I want to be able to create many Tasks and I want those tasks to be linked to this Step. To do so, I created all the proper admin classes (one for Task and one for Step).

Here's what I do that causes my problem. When I try to create a Step, I can create the tasks and even reorder them, which is great and all done automatically by SonataAdminBundle. When I click on save, everything is saved in the database, except that in the database, the id of the step is not set in the row of the Task. Therefore, the tasks are not linked to the Step...

Here's my Step's admin class:

<?php
// src/Acme/DemoBundle/Admin/PostAdmin.php

namespace IMA\ProcessManagementBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class StepAdmin extends Admin
{
    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name', 'text', array('label' => 'Nom de l\'étape'))

            ->add('tasks', 'sonata_type_collection', array(), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'positionNumber'
            ))
            ->add('positionNumber', 'integer', array('label' => 'Position'))
        ;
    }

    // Fields to be shown on filter forms
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('name')

        ;
    }

    // Fields to be shown on lists
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('slug')
        ;
    }
}

Here's also my Task admin class:

<?php
// src/Acme/DemoBundle/Admin/PostAdmin.php

namespace IMA\ProcessManagementBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class TaskAdmin extends Admin
{
    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name', 'text', array('label' => 'Tâche'))
            ->add('positionNumber', 'integer', array('label' => 'Position'))

        ;
    }

    // Fields to be shown on filter forms
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('name')

        ;
    }

    // Fields to be shown on lists
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('slug')
        ;
    }
}

Also, here are the description of my entities

IMA\ProcessManagementBundle\Entity\Step:
    type: entity
    table: null
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        name:
            type: string
            length: 255
        positionNumber:
            type: integer


    oneToMany:
        tasks:
            targetEntity: Task
            mappedBy: step
            cascade: ["persist", "merge"]

    lifecycleCallbacks: {  }


IMA\ProcessManagementBundle\Entity\Task:
    type: entity
    table: null
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        name:
            type: string
            length: 255
        positionNumber:
            type: integer


    manyToOne:
        step:
            targetEntity: Step
            inversedBy: tasks


    lifecycleCallbacks: {  }

I'm wondering why the id of the Step is not set in the Task row...

  • 写回答

2条回答 默认 最新

  • douquanzhan0315 2014-02-05 11:57
    关注

    You need to manually attach the step to the tasks, to do so you need to use the prePersist and preUpdate methods in the step admin class...

    The reason for this is that the developers of the SonataAdminBundle say it's doctrine's concern to handle this and the Doctrine developers say it is the bundles responsibility... So for now we need to do it for ourselves.

    This would be your new stepAdmin class:

    <?php
    namespace IMA\ProcessManagementBundle\Admin;
    
    use Sonata\AdminBundle\Admin\Admin;
    use Sonata\AdminBundle\Datagrid\ListMapper;
    use Sonata\AdminBundle\Datagrid\DatagridMapper;
    use Sonata\AdminBundle\Form\FormMapper;
    
    class StepAdmin extends Admin
    {
        // Fields to be shown on create/edit forms
        protected function configureFormFields(FormMapper $formMapper)
        {
            $formMapper
                ->add('name', 'text', array('label' => 'Nom de l\'étape'))
    
                ->add('tasks', 'sonata_type_collection', array(), array(
                    'edit' => 'inline',
                    'inline' => 'table',
                    'sortable'  => 'positionNumber'
                ))
                ->add('positionNumber', 'integer', array('label' => 'Position'))
            ;
        }
    
        // Fields to be shown on filter forms
        protected function configureDatagridFilters(DatagridMapper $datagridMapper)
        {
            $datagridMapper
                ->add('name')
    
            ;
        }
    
        // Fields to be shown on lists
        protected function configureListFields(ListMapper $listMapper)
        {
            $listMapper
                ->addIdentifier('name')
                ->add('slug')
            ;
        }
    
    
        public function prePersist($object)
        {
            foreach ($object->getTasks() as $task) {
                $task->setStep($object);
            }
        }
    
        public function preUpdate($object)
        {
            foreach ($object->getTasks() as $task) {
                $task->setStep($object);
            }
        }
    
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效