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

时间:2014-01-29 01:29:53

标签: php symfony sonata-admin

我正在使用SonataAdmin(和Symfony2)来管理我的实体。我在一个步骤和许多任务之间有一个oneToMany关系。由于一个步骤可以包含许多任务,因此当我创建一个步骤时,我希望能够创建许多任务,并且我希望将这些任务链接到此步骤。为此,我创建了所有正确的管理类(一个用于Task,一个用于Step)。

这就是我所做的,这会导致我的问题。当我尝试创建一个Step时,我可以创建任务甚至重新排序它们,这很棒,并且全部由SonataAdminBundle完成。当我单击“保存”时,所有内容都保存在数据库中,但在数据库中,步骤的ID未在“任务”行中设置。因此,任务没有链接到步骤...

这是我的Step的管理类:

<?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')
        ;
    }
}

这也是我的任务管理类:

<?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')
        ;
    }
}

此外,这里是我的实体的描述

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: {  }

我想知道为什么步骤的ID没有在任务行中设置...

2 个答案:

答案 0 :(得分:21)

您需要手动将步骤附加到任务,为此您需要在步骤管理类中使用prePersist和preUpdate方法...

原因是SonataAdminBundle的开发人员说这是处理这个问题的理论,而且Doctrine开发人员说这是捆绑责任......所以现在我们需要自己做。

这将是您的新stepAdmin课程:

<?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 :(得分:2)

Step实体中,您必须添加addTask方法:

class Step
{
    //...

    public function addTask($tasks)
    {
        $tasks->setStep($this);
        $this->tasks[] = $tasks;

        return $this;
    }

    //...
}

由于您尚未提供Step.php,因此您应该适应此代码。