簡體   English   中英

symfony3:為具有多對一關系的列的實體創建表單

[英]symfony3: create form for entity that has a column with many to one relationship

我有一個“任務”表,引用一個“Estados”表,其中包含從Tasks.taskestado列到Estados.estado的外鍵。

這是任務的相關XML映射:

<entity name="AppBundle\Entity\Tasks" table="TASKS" repository-class="AppBundle\Repository\TasksRepository">
<id name="taskid" type="bigint" column="TaskID">
  <generator strategy="IDENTITY"/>
</id>
...
<many-to-one field="taskestado" target-entity="Estados" fetch="LAZY">
  <join-columns>
    <join-column name="TaskEstado" referenced-column-name="Estado"/>
  </join-columns>
</many-to-one>
...

而對於Estados:

<entity name="AppBundle\Entity\Estados" table="ESTADOS">
<id name="estado" type="string" column="Estado" length="15">
  <generator strategy="IDENTITY"/>
</id>
<field name="estadodescricao" type="string" column="EstadoDescricao" length="50" nullable="true">
  <options>
    <option name="fixed"/>
  </options>
</field>
...

鑒於此,我正在嘗試創建一個動作(novaAction())來創建任務。 這是Controller代碼:

public function novaAction(Request $request)
{
    $task = new Tasks();
    $em = $this->getDoctrine()->getManager();

    dump($task);
    #$task->setTaskEstado(new Estados());
    $form = $this->createForm(TasksType::class, $task);
    $form->handleRequest($request);

    if ($form->isSubmitted()) {
        if ($form->isValid()) {
            // Criar a tarefa na BD
            $em->persist($form->getData());
            $em->flush();
            $this->addFlash('notice', 'app.nova_tarefa.mensagem_sucesso');

            return $this->redirectToRoute('nova_tarefa');
        }

        $this->addFlash('error', 'app.nova_tarefa.mensagem_erro');
    }

以及相關的TasksType代碼:

class TasksType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('taskid', HiddenType::class)
        ...
        #->add('taskestado')
        ->add('taskestado', EntityType::class, [ 'class' => 'AppBundle:Estados' ])
        ...
}

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Tasks',
        #'empty_data' => function (\Symfony\Component\Form\FormInterface $form) {
        #    #return new Tasks($form->get('tasks')->getData());
        #    return new Tasks();
        #},
    ));
}
}

'empty_data'選項是嘗試創建表單而不向其傳遞任務實例。 另外,當我使用注釋代碼添加taskestado時,我也有相同的結果,即沒有參數。

這是相關的任務實體:

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * Tasks
 */
class Tasks
{
    /**
     * @var integer
     */
    protected $taskid;

    /**
     * @var \AppBundle\Entity\Estados
     */
    protected $taskestado;

    ...

    /**
     * Get taskid
     *
     * @return integer
     */
    public function getTaskid()
    {
        return $this->taskid;
    }

    /**
     * Set taskestado
     *
     * @param \AppBundle\Entity\Estados $taskestado
     *
     * @return Tasks
     */
    public function setTaskestado(\AppBundle\Entity\Estados $taskestado = null)
    {
        $this->taskestado = $taskestado;

        return $this;
    }

    /**
     * Get taskestado
     *
     * @return \AppBundle\Entity\Estados
     */
    public function getTaskestado()
    {
        return $this->taskestado;
    }

    ...
}

當我打開頁面時,出現以下錯誤:

必須管理傳遞到選擇字段的實體。 也許堅持他們在實體經理?

我還生成了CRUD( bin/console doctrine:generate:crud --filter=Tasks ),這樣我就可以檢查它是如何完成的,但代碼是相似的,以及結果(在修復了一些問題之后)某些日期時間列的TasksType)。

我究竟做錯了什么?

如錯誤所示,您需要在任務的映射中設置cascade = persist。 例如:

<many-to-one field="taskestado" target-entity="Estados" fetch="LAZY">
  <cascade>
     <cascade-persist/>
  </cascade>
  <join-columns>
    <join-column name="TaskEstado" referenced-column-name="Estado"/>
  </join-columns>
</many-to-one>

而不是做$em->persist($form->getData()); 使用$em->persist($task);

看看是否有效......

我終於得到了答案,這遠非顯而易見。

正如我在問題中所說,從Tasks.taskestado到Estados.estado之間存在多對一的關系。 Estados.estado是一個字符串,可以為空,空字符串或(通常)非空字符串。 雖然未在映射中指出,但空字符串是taskestado的默認值。

我已經在表上有數據,並且Estados.estado的一個條目恰好是空字符串。

我沒有在問題中發帖,但我在此異常的堆棧跟蹤中看到了以下信息:

[1] Symfony\Component\Form\Exception\RuntimeException: Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
    at n/a
        in /var/www/simpletask2/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php line 119

    at Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader->getIdValue(object(Estados))
        in  line 

    at call_user_func(array(object(IdReader), 'getIdValue'), object(Estados))
        in /var/www/simpletask2/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php line 204

    at Symfony\Component\Form\ChoiceList\ArrayChoiceList->flatten(array(object(Estados), object(Estados), object(Estados), object(Estados), object(Estados), object(Estados), object(Estados), object(Estados)), array(object(IdReader), 'getIdValue'), array(), array(), array())
        in /var/www/simpletask2/vendor/symfony/symfony/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php line 91

因此,EntityType從數據庫中檢索值並嘗試呈現它們。 換句話說,它們已經存在,問題實際上並不在於我如何初始化實體。

所以,我記得Estados實體的空字符串值,並試圖將其從數據庫中刪除:問題解決后,TaskEstado實體被初始化並按預期呈現。

現在我需要一種解決方法,但找到了解決方案。

感謝大家的回答。

確保你擁有

$this->taskestado = new ArrayCollection();

在您的Tasks類的__construct()中。

然后2個通知:

盡量只在代碼中使用英語。 通過這種方式,您可以獲得更多響應 作為“最佳實踐”,使用Singulars作為您的實體類名稱Like TaskTaskEstado

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM