Symfony2表单,其中数据对象与需要填写的内容完全不匹配

Die*_*ter 2 forms validation symfony

我们有一个监控服务,我们的监控单元会关注某些机器.

我正在创建一个表单来在Symfony2中注册一台新机器.

所以我们有机器实体:

  • ID
  • 机器名称
  • 监控ID

监控实体:

  • ID
  • 序列号
  • ...

对于新机器,客户需要填写表格:

  • 机器名称
  • 连接监视器的序列号
  • ...

现在,如果我用一个机器实体作为数据支持来制作一个表单,我就没有"字段"来询问序列号.Symfony不允许它,因为后备实体没有名为"序列号"的字段.

我怎么能够:

  • 请求序列号,而后备实体中没有此类字段
  • 如果我得到序列号,我怎样将其与内部id链接起来,以便在数据经过验证和绑定后与实体保持一致

我想我可以:

  • 如@weaverryan在这篇优秀文章中所描述的那样,制作一个没有背后的对象的表单:http://knplabs.com/en/blog-csi/symfony-validators-standalone - 这样我自己坚持,但我需要我的自定义表单和我的机器实体的单独约束,这是一个遗憾.
  • 提供某种链接,以便Symfony知道从哪里获得序列号字段存在的事实,以及它的约束是什么.也许通过定义关系?我希望在我的实体代码中避免关系,因为我在邮件列表上看到了很多问题,但也许我别无选择:-)
  • 还要别的吗?

我希望我能解释这一点.我想很多人都必须解决这个问题.我想我只是在寻找一些非常标准的Symfony功能,只是因为我不确定它叫什么:-)

小智 5

首先,你应该使用关系 - 即机器有一个监控.我认为人们对此有疑问,因为当你习惯于用"id"和外键来思考事物时,以完全面向对象的方式思考关系是新的:).

因此,假设您的计算机与Monitor相关,您现在可以创建一个嵌入MonitorType的MachineType(它将是一个包含serialnumber字段的表单).然后,在提交复合表单时,将使用Monitor类上的serialnumber约束.

默认情况下,绑定所有这些时,它将创建一个新的Machine对象,并通过$ machine-> getMonitor()提供新的Monitor对象.如果你坚持,这将是两个插入.但是,我猜你宁愿用它的序列号查找监视器并使用现有的监视器,对吗?这样做很简单,只需在绑定表单后短路即可.

$form = new MachineType();
$form->bindRequest($request);
if ($form->isValid()) {
    $em = $this->getDoctrine()->getEntityManager();
    $machine = $form->getData();
    $serialNumber = $machine->getMonitor->getSerialNumber();

    $existingMonitor = $em
        ->getRepository('YourBundle:Monitor')
        ->findOneBy(array('serialNumber' => $serialNumber));
    if ($existingMonitory) {
        $machine->setMonitor($existingMonitor);
    }

    $em->persist($machine);
    $em->persist($machine->getMonitor());
    $em->flush();

    // ...
}
Run Code Online (Sandbox Code Playgroud)

所以,这就是主意.最重要的是,通过不使用关系,你会让自己处于劣势.你看,通过这两种形式嵌入在一起,你真的必须的SERIALNUMBER场自然访问.

祝好运!