Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 实体';SonataAdmin中的OneToMany关系中未保存父项的id_Php_Symfony_Sonata Admin - Fatal编程技术网

Php 实体';SonataAdmin中的OneToMany关系中未保存父项的id

Php 实体';SonataAdmin中的OneToMany关系中未保存父项的id,php,symfony,sonata-admin,Php,Symfony,Sonata Admin,我使用SonataAdmin(和Symfony2)来管理我的实体。我在一个步骤和许多任务之间有一种单一的关系。因为一个步骤可以包含许多任务,所以当我创建一个步骤时,我希望能够创建许多任务,并且希望这些任务链接到此步骤。为此,我创建了所有适当的管理类(一个用于任务,一个用于步骤) 这就是我所做的导致我的问题的事情。当我尝试创建一个步骤时,我可以创建任务,甚至可以对它们重新排序,这非常好,所有这些都是由SonataAdminBundle自动完成的。当我单击save时,所有内容都保存在数据库中,但在数

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

这就是我所做的导致我的问题的事情。当我尝试创建一个步骤时,我可以创建任务,甚至可以对它们重新排序,这非常好,所有这些都是由SonataAdminBundle自动完成的。当我单击save时,所有内容都保存在数据库中,但在数据库中,步骤的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')
        ;
    }
}

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

在您的
步骤
实体中,您必须在addTask方法中添加:

class Step
{
    //...

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

        return $this;
    }

    //...
}

由于您尚未给出
Step.php
,因此您应该适当地修改此代码。

您需要手动将步骤附加到任务,为此,您需要使用Step admin类中的prePersist和preUpdate方法

原因是SonataAdminBundle的开发人员表示,处理这一问题是原则的考虑,原则开发人员表示,这是捆绑包的责任。。。所以现在我们需要自己去做

这将是您的新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);
        }
    }


}

由于我指定了多人和一人的关系,这不是正常自动完成的吗?不,这不是自动完成的。在新请求中可能会出现这种情况,因为随后将从数据库中提取实体(一切都会井然有序)。在以下情况下,这会给您带来麻烦,如果您创建新步骤并尝试添加任务,则会出现以下错误:“传递到选项字段的实体必须进行管理”。这是因为您将以“$This”作为参数调用“setStep”,但该实体尚未持久化。在我上面的示例中,这个问题没有出现,因为您的实体已准备好插入,并且您已经“管理”了实体。
app/console原则:schema:validate
告诉您什么?在将新的
步骤添加到
任务中时,可能会重复此操作,但不用于删除步骤!实际上,
preUpdate()
函数不知道删除哪个步骤,因为前面的情况未知,因为
$object->getTasks()
给出了已验证表单的情况。怎么解决?我所做的就是使用条令快照。在集合中,调用getSnapshot(),然后将两者进行比较。也许这不是最好的方法。@Blacksad:不知道它是否仍然相关,但请尝试在
@ORM\OneToMany()
选项
中指定。这为我解决了相关实体移除问题。谢谢@geert wille!今天救了我:)
<?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);
        }
    }


}