3

我有一个与“城市”实体具有多对一关系的“人”实体:

这是人的关系映射:

/**
* @ORM\ManyToOne(targetEntity="City", inversedBy="persons", cascade={"persist"})
*/
private $city;

和城市的:

/**
* @ORM\OneToMany(targetEntity="Person", mappedBy="city")
*/
private $persons;

我使用由教义生成的基本 Symfony 2 'person' 控制器:generate:crud:

$entity  = new Person();
$form = $this->createForm(new PersonType(), $entity);
$form->bind($request);

if ($form->isValid()) {

        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();
}

PersonType 表单类型实例化了一个 CityType

class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
        $builder
        ->add('city', new CityType())
        ->add('firstname')
        ->add('lastname')
        ->add('gender')
        ...

CityType 表单类型有一个文本字段

class CityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('cityname', 'text');
     }
}

当我提交表单时,会创建 Person 实体以及 City 实体,这要归功于 cascade={"persist"}。

当我用数据库中已经存在的城市名称填写表格时,问题出现了,Doctrine 创建了另一个具有相同城市名称的条目。

Doctrine 是否有一种简单的方法可以检测到这一点,并使用 Person 表中现有的 city_id ?

4

2 回答 2

2

一种解决方案是,不要级联持久化实体。IE

    if ($form->isValid()) {
        $data = $form->getData();
        $em = $this->getDoctrine()->getEntityManager();

        $city = $em->getRepository('YourBundle:City')
                   ->findOneByCityname($data['cityname']);

        if($city == null){
            $city = new City();
            $city->setName($data['cityname']);
            $em->persist($city);
            $em->flush();
        }

        $entity->setCity($city);
        $em->persist($entity);
        $em->flush();
    }
于 2012-10-27T04:04:26.840 回答
2

正如@vadim 所说,您必须使用datatransformer。一开始可能会令人困惑,但大约 30 分钟后你就会学会它。请记住,在世界各地,您将拥有许多同名的城市。

最好的解决方案是这样;在该文本字段中,用户将键入一个名称,如Belgrade, Montana, Usa(顺便说一句;贝尔格莱德是塞尔维亚的首都,只是给你一个同名城市的例子)。Datatransformer 将读取 DB 并找到您可以链接的正确的贝尔格莱德城市。

完成此操作后(非常简单),您可以为该字段构建自动完成功能。@artworkad 的建议过于复杂,以后会带来更多的问题。

于 2012-10-27T17:57:22.113 回答