Select 或创建一个实体

Select or create an entity

我通常会在研究后找到解决问题的答案,但今天情况并非如此。

假设我有 2 个实体,"Task" 和 "TaskCategory",每个任务都有一个类别。 我想让我的用户不仅可以将现有类别归于他们的任务,还可以创建新类别。

这是我目前的代码:

<?php
// TaskCategoryType.php
class TaskCategoryType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
        ;
    }
// Some stuff...

<?php
// TaskType.php

// Some stuff...

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // Add some fields there
            ->add(
                'category',
                TransformableEntityType::class,
                ['class' => 'AppBundle:TaskCategory']
            )
            ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
                $task = $event->getData();
                $form = $event->getForm();
                if (empty($task['category']['id']) && !empty($task['category']['name'])) {
                    $task['category']['id'] = null;
                    $event->setData($task);
                    $form->remove('category');
                    $form->add('category', TaskCategoryType::class);
                }
            })
        ;
    }

// Some stuff...

它可以很好地创建任务,但是当我编辑现有任务时,它会编辑关联的 TaskCategory 而不是创建新任务。 我试图强制创建一个新的 TaskCategory : $task['category']['id'] = null;但它不起作用。

感谢您的帮助,我真的被困住了:(

编辑:我忘了说我只是将此表单用作 API,这就是为什么我只有一个 'category' 字段,否则我会使用另一个 'category_new'场.

好吧,我似乎终于找到了一些可行的方法,它不是很漂亮,我对它的完成方式不太满意,但目前我还没有找到任何替代方法。 如果您有更简洁的解决方案,我将很乐意学习。

<?php
class TaskType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
      $builder

        // Some fields...

        ->add(
            'category',
            TransformableEntityType::class,
            ['class' => 'AppBundle:TaskCategory']
        )
        ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
            $task = $event->getData();
            $form = $event->getForm();
            if (empty($task['category']['id']) && !empty($task['category']['name'])) {
                // If there is no category id but there is a category
                // name it means it is a new category. so replace 
                // the custom entity field with this simple field
                $form->remove('category');
                $form->add('category', TaskCategoryType::class, ['allow_extra_fields' => true]);
            }
        })
        ->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
            $catForm = $event->getForm()->get('category');
            if ($catForm->has('name') && $catForm->get('name')->getData() !== "") {
                // If there is a category name it means 
                // it is a new category. 
                $category = new TaskCategory(); // Create new category
                $category->setName($catForm->get('name')->getData());
                $task = $event->getData()->setCategory($category);
                $event->setData($task);
            }
        })
    ;
}

考虑到您已为从 TaskTaskCategory 的关联启用 cascade-persist。我想最好的解决方法是使用一个 autocompleter ,它应该作为基于标签的。

如果给定的 TaskCategory 可用,Transformer 应该检查数据库,否则创建一个新的。