Symfony 2 - 表单选择项数据库

4

我是Symfony 2的初学者。

我正在尝试展示一个带有“select”选项的表单,这些“options”来自一个查询。

我将以下代码放在我的表单中:

use Doctrine\ORM\EntityRepository;
use Bloc\MainBundle\Entity\Table;
use Bloc\MainBundle\Entity\Table2;

public function addAction(Request $request)
{
    $table = new Table();
    $form = $this->createFormBuilder($table , array('attr' => array('role' => 'form')))
        ->add('num', 'integer', array('label' => 'Numéro', 'attr' => array('class' => 'form-control')))
        ->add('nom_emetteur', 'text', array('label' => 'Emetteur', 'attr' => array('class' => 'form-control')))
        ->add('numero', 'entity', array('class' => 'BlocMainBundle:Table2', 'property' => 'numero'))
        ...
}

我出现了以下错误:

Neither the property "numero" nor one of the methods "getNumero()", "isNumero()", "hasNumero()", "__get()" or "__call()" exist and have public access in class "Bloc\MainBundle\Entity\Table". 

我明白这个错误告诉我"numero"不在实体表中,但我质疑的是实体表2。 我一定漏掉了什么,但我不知道在哪里...
我的实体定义如下: 表1:
<?php...
class Table
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="num", type="integer")
     */
    private $num;

    //Getter and setter...
}

Table 2
表格2
<?php

namespace Bloc\MainBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Fournisseur
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Bloc\MainBundle\Entity\Table2Repository")
 */
class Table2
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(name="numero", type="integer")
     */
    private $numero;

    /**
     * Set numero
     *
     * @param integer $numero
     * @return Fournisseur
     */
    public function setNumero($numero)
    {
        $this->numero = $numero;

        return $this;
    }

    /**
     * Get numero
     *
     * @return integer 
     */
    public function getNumero()
    {
        return $this->numero;
    }
    ...
}

你能帮我吗?


你能发布一下TableTable2的实体定义吗? - Ken Hannel
"numero" 应该是 Table2 的外键。需要查看您的实体才能回答这个问题。 - dmnptr
我尚未在我的两个实体之间建立关系,稍后再做。 - jlafforgue
3个回答

10

如果您未设置关系,则需要告诉FormBuilder不将其映射到字段。

->add('numero', 'entity', array(
    'mapped'   => false, 
    'class'    => 'BlocMainBundle:Table2',
    'property' => 'numero',
));
为了按照您的需求(使用多个字段作为选项文本)完成选项,您需要使用“choice”类型并像这样构建选项列表:
->add('numero', 'choice', array(
    'mapped'  => false,
    'choices' => $this->buildChoices()
));

protected function buildChoices() {
    $choices          = [];
    $table2Repository = $this->getDoctrine()->getRepository('BlocMainBundle:Table2');
    $table2Objects    = $table2Repository->findAll();

    foreach ($table2Objects as $table2Obj) {
        $choices[$table2Obj->getId()] = $table2Obj->getNumero() . ' - ' . $table2Obj->getName();
    }

    return $choices;
}

如果我想要返回我的表格中选项的两个属性作为数字和名称,我是否需要在实体Table2中创建一个setter和getter? - jlafforgue
我不太确定我完全理解了。您是想使用Table2中字段numero的值作为选择字段的选项,对吗? - Ken Hannel
我很费劲地寻找合适的词语;我希望在我的渲染结果中得到这个 <select ...><option ...>112 - name1</option><option>113 - name2,不仅仅是“numero”,而且还有“name”,这两个字段都在 Table2 中。 - jlafforgue
好的,请给我一两分钟时间,我会更新我的答案,告诉您如何正确地使用一个字段作为值另一个字段作为选项文本。 - Ken Hannel
我阅读了文档,其中提供了一个几乎相似的示例,但不幸的是我遇到了另一个错误:“期望类型为“对象或数组”的参数”,但实际给出的是“整数”... 我会继续寻找,非常感谢您的帮助。 - jlafforgue
回到电脑上进行了测试并更新了答案,提供了正确的解决方案。 - Ken Hannel

2

你可以使用这个解决方案。它非常简单,来自Symfony2的文档。我正在使用这个。

->add('numero', 'entity', array(
            'class' => 'BlocMainBundle:Table2',
            'choice_label' => 'numero' // MAGIC read next paragraph, it is a private variable
        ))

就像文档中写的一样:

如果实体对象没有__toString()方法,则需要使用choice_label选项。

使用这个解决方案,因为它是Symfony针对这种情况的本地解决方案:)

我希望能帮助您或其他人


1
如果你需要信息表,你可以在你的Form类中创建一个构造函数。
在你的控制器中:
$emForm = $this->getDoctrine()->getRepository('RelacionesDoctrineBundle:Adolecente');

$asignatura = new AsignaturasType($emForm);// your form class

在你的表单类中。
class AsignaturasType extends AbstractType {

      protected $repository;

          function __construct($repository)
             {
               $this->repository = $repository;
             }
}

完成了!你可以使用它:

  $findAdolecente    = $this->repository->findAll();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接