我错过了使用Form :: handleRequest

时间:2014-05-08 10:39:27

标签: php symfony doctrine-orm symfony-forms

背景:

我已经构建了一个表单,可以同时批量编辑同一类型的多个实体。表单可以正常工作,它可以保存对公开字段所做的更改。

我使用从数据库中提取的实体数组初始化表单数据。 $form->handleRequest($request)使用相同的实体数组来标识哪个实体已更改,并使用其setter来更改其更改的属性。

不幸的是$form->handleRequest($request)正在根据实体的数组索引识别表单数据和实体之间的对应关系。

这意味着如果数据在DB中发生更改,排序会发生变化,$form->handleRequest($request)会尝试更新错误的实体对象,因为排序顺序不完全匹配。

更正尝试:

  1. 我在表单中添加了id作为隐藏字段,希望Symfony2可以使用它来初始化要更新的对象......

    ...但是Symfony2试图使用setId($newId)而我没有为该属性定义一个setter。所以我添加了setter,如果$newId !== $this->id - 它做了 - 如果你切换行,或者尝试只保存一行(通过ajax)或者你从中删除行,我就会抛出异常表格(通过JS)。

  2. 我试图在查询中使用INDEX BY来获取希望匹配器算法通过数组键匹配日期>实体的实体...也不起作用。

  3. 问题:

    我显然是以错误的方式解决这个问题。我没有按照它的设计方式使用它。

    Symfony2可能还有另一个批量更新内容的工作流程。也许只有在通过ID在实体上初始化表单时才应使用handleRequest。也许我不应该使用handleRequest并构建我自己的自定义逻辑来更新更改的内容。

    代码:

    控制器:

    class AAAAController extends Controller
    {
        public function AAAAEditAction(Request $request, $filters)
        {
            $AAAAs = $AAAArepo->findBy($filters);
    
            $form = $this->createForm(new MultiAAAAType(), array('AAAAs' => $AAAAs))
                ->handleRequest($request);
    
            foreach ($AAAAs as $AAAA) {
                $em->persist($AAAA);
            }
            $em->flush();
        }
    }
    

    主窗体(包含一个单独的收集字段):

    class MultiAAAAType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add(
                'single_aaaa',
                'collection',
                array(
                    'type' => new SingleAAAAType(),
                )
            );
        }
    }
    

    子表单(包含需要编辑的特定字段):

    class SingleEntityType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            // adding actual fields here
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(
                array(
                    'data_class' => '\...\Entity\AAAA',
                )
            );
        }
    }
    

    此外:

    我知道在进行匹配后,$form->submit曾经是常态(使用here)和handleRequest调用submit

    我同意,如果我使用$em->merge更新实体,手动进行匹配并不会那么糟糕。解决方案是几行代码(如我提到的答案)。

    但现在的问题是“我做错了吗?我是否应该使用上述解决方案?handleRequest是不是设计用来处理这种情况?”。

    如果handleRequest无法处理这种情况,则意味着它无法正确处理关联,而不会进入同一个pickle。

0 个答案:

没有答案