Symfony表单有ManyToOne字段,但仍然需要__tostring()函数

时间:2016-03-26 20:59:59

标签: symfony

在存储客户端地址信息的Symfony实体中,我与包含所有国家/地区的实体建立了ManyToOne连接。所以该实体具有以下链接:

/**
 * @var string
 *
 * @ORM\Column(name="country_code", type="string", length=2)
 *
 * @ORM\ManyToOne(targetEntity="Country")
 * @ORM\JoinColumn(name="country_code", referencedColumnName="country_code")
 */
private $countryCode;

在这个实体生成的表单中,我将其定义如下:

       ->add('countryCode', 'entity', array(
            'class' => 'MyBundle:Country',
            'choice_label' => 'name_en',
            'choice_value' => 'country_code',
            'data' => 'nl',
        ))

因此它不存储主键,而country_code则存储两个字母的代码,如" nl"为荷兰。

然后我必须添加__tostring()代码才能使它工作,但为什么呢?我虽然不再需要__tostring函数,因为已经存在ManyToOne连接。

public function __toString()
{
    return strval($this->countryCode);
}

2 个答案:

答案 0 :(得分:0)

我猜你错过了关于数据库如何存储关系的信息。

第一个问题:您不需要这个:

@ORM\Column(name="country_code", type="string", length=2)

...因为@ORM\ManyToOne已经描述了此属性的架构。

在这里,我们遇到第二个问题@ORM\ManyToOne创建一个整数列,其中包含相应国家/地区实体的ID。这意味着,当您为此属性创建表单字段时,它不知道应该将哪个属性呈现为字符串表示形式,因为您的地址簿(或任何您称之为)的实体仅存储数字,而不是国家/地区代码。< / p>

答案 1 :(得分:0)

首先在你的实体中你必须写下这个:

/**
* @ORM\ManyToOne(targetEntity="PathTo/YourBundle/Entity/Country")
*/
private $country;

然后$ country将引用国家实体(它在数据库中的ID), 并允许您访问所有的字段。

在您的表单中,您不应该使用

->add('country', 'entity', array(....

由于不推荐使用此语法,请改为使用:

use Symfony\Bridge\Doctrine\Form\Type\EntityType; //don't forget it on top of your form file


->add('country', EntityType::class, array(....

由于您可能希望按字母顺序订购国家/地区,因此您将使用查询来执行此操作,最终您的代码可能如下所示:

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;

...

->add('country', EntityType::class, array(
      'class' => 'MyBundle:Country',
      'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('c')
                        ->orderBy('c.name_en', 'ASC');
                },
      'choice_label' => 'name_en',
      'data' => 'nl'
      ))

您通常不必担心choice_value,这将是所选国家/地区的唯一ID:当您访问客户实体时,您将执行以下操作:

$client->getCountry()->getCountryCode() ;

获取国家/地区代码。