【问题标题】:Symfony2 embedded forms and database duplicatesSymfony2 嵌入式表单和数据库副本
【发布时间】:2014-02-26 03:02:07
【问题描述】:

我有一个与实体 User 相关的表单 UserType。 这个表单调用另一个表单:CityType

<?php

namespace ...\SiteBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('city', new CityType(), array('label' => false))
                ->add(...);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'FindBack\SiteBundle\Entity\User',
            'cascade_validation' => true
        ));
    }
    // ...
}

User 关联表如下所示:

id | city_id | ...
---|---------|-----
1  | 1       | ...
2  | 1       | ...
3  | 2       | ...

这里是城市类型

<?php

namespace FindBack\SiteBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

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

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'FindBack\SiteBundle\Entity\City',
        ));
    }

    public function getName()
    {
        return 'city';
    }
}

所以当我通过 UserType 表单创建 User 时,会创建一个新的City。 如果我使用相同的城市名称(即:Marseille)创建 User 两次,我的数据库将如下所示:

id  name
--|----------
1 | Marseille
2 | Marseille
3 | Paris
...

所以有一个重复,我想避免它! 我该如何进行?我尝试为 City 表的 name 字段设置唯一约束,但是当我想创建另一个 User 时," SQLSTATE[23000]:完整性约束违规:1062 Symfony2 抛出了键 'name' 的重复条目 'Marseille'。这似乎是合乎逻辑的。

如果数据库中已经有一个名为“马赛”的城市,我是否需要检查与用户关联的控制器,然后将现有的 City 关联到我的 User

【问题讨论】:

  • 为什么不提供一个已经将城市插入数据库的解决方案?
  • @DonCallisto 我不确定你的意思...我不会用来自法国的所有城市来填充我的数据库!
  • 那么,如果我要用“城市:月球火箭”填充你的字段,你会接受吗?
  • @DonCallisto 实际上,城市名称是由 Google Places 自动填充的(用户在 google Places 自动完成字段中输入一个地点。然后我取回城市值并填充城市名称字段,这要归功于jQuery)。不过没关系,这不是问题。
  • 因此,如果您接受“标准名称”(因此来自 google 地方),您必须先验证该城市是否已经进入数据库,然后采取适当的措施

标签: php forms symfony doctrine-orm duplicates


【解决方案1】:

首先你需要:

  • 用于发布表单的控制器
  • 城市实体的存储库

这只是一个示例,因为我对您的应用程序一无所知:

use Symfony\Component\HttpFoundation\Request;

public function registerUserAction(Request $request) {
  [...]
  $cr = $this->getDoctrine()->getManager()->getRepository('CityRepository');
  [...]
  $user = new User();
  $form = $this->createForm(new $form(...), $user);
  $form->bind($request);
  //get the field from form
  $cn = $request->get('city_name');
  //search for a pre existent entity
  $city = $cn->findOneByCityName($cn);
  if($city) {
    $user->setCity($city);
  }
  if($form->isValid()){
    [...]
  }
}

【讨论】:

  • 这似乎是一种解决方法,我很惊讶 Symfony2 没有提供另一种方法来做到这一点。此外,如果我想检查姓名和其他十二个字段,我是否需要对所有这些重复该过程?
  • @peltho:您可以在表单字段上定义自己的约束并让 symfony2 为您检查它们(使用-&gt;isValid() 方法)。但是这种特定情况是不同的,因为您不仅会检查,还会在检查时执行一些其他操作...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多