在存储客户端地址信息的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);
}
答案 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() ;
获取国家/地区代码。