Symfony2形式,其中数据对象不完全匹配需要填写的内容 [英] Symfony2 form where the data objects doesn't match exactly what needs to be filled in

查看:134
本文介绍了Symfony2形式,其中数据对象不完全匹配需要填写的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

我们有一个监视服务,我们的监视器单元密切关注某些机器。 p>

因此,我们有机器实体


  • id

  • 机器名称

  • 显示器编号



监视器实体


  • id

  • serialnumber



  • 对于新机器,客户需要填写表格 strong> with:


    • 计算机名称

    • 连接的监视器的序列号
    • ...



    现在,如果我用一个表单作为数据支持,创建一个机器实体, 'field'在其中询问序列号。 Symfony不支持它,因为支持实体没有名为序列号的字段。



    我该如何做:




    • 询问序列号,而支持实体中没有这样的字段
    • 如果我得到序列号,我该如何将其与内部ID相关联,以便在数据验证和绑定后与实体保持一致



    我可以:

    >


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

    • 其他?



    我希望我解释这个权利。我想很多人都必须解决这个问题。我想我只是看一些非常标准的Symfony功能,只是因为我不确定它叫什么: - ) 首先,你应该使用关系 - 即机器有一个监控。我认为人们在这方面遇到了问题,因为当你习惯于用id和外键来思考事物时,以完全面向对象的方式来考虑关系是新的:)。

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



    默认情况下,当您绑定所有这些时,它会创建一个新的Machine对象,通过$ machine-> getMonitor()提供一个新的Monitor对象。如果你坚持,这将是两个插入。但是,我猜你宁愿用serialnumber查看显示器,并使用现有的显示器,对吧?要做到这一点很简单,只需在绑定表单后短路即可。

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

    $ existingMonitor = $ EM
    - > getRepository( YourBundle:监控)
    - > findOneBy(阵列( SERIALNUMBER => $ SERIALNUMBER));
    if($ existingMonitory){
    $ machine-> setMonitor($ existingMonitor);
    }

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

    // ...
    }

    这个想法。最大的问题是,如果不使用关系,你会使自己处于劣势。你看,通过将这两个表单嵌入到一起,你真的可以自然地访问serialnumber字段。



    祝你好运!


    We have a monitoring service where our monitor units keep an eye on certain machines.

    I'm creating a form to register a new machine in Symfony2.

    So we have the machine entity:

    • id
    • machine name
    • monitor id

    And the monitor entity:

    • id
    • serialnumber
    • ...

    For a new machine, the customer needs to fill the form with:

    • machine name
    • serialnumber of attached monitor
    • ...

    Now, if I make a form with, as data backing, a machine entity, I have no 'field' in which to ask for the serial number. Symfony doesn't allow it, since the backing entity doesn't have a field named 'serial number'.

    How can I:

    • ask for the serial number while there is no such field in the backing entity
    • if I get the serial number, how do I link it up with it's internal id to persist with the entity once the data is validated and bound

    I figure I can:

    • make a form without an object behind it, as described by @weaverryan in this excellent article: http://knplabs.com/en/blog-csi/symfony-validators-standalone - this way I do the persisting myself, but I need separate constraints for my custom form, and for my machine entity, which is a pity.
    • provide some kind of link so that Symfony knows where to get the fact that a serialnumber field exists, and what it's constraints are. Perhaps by defining a relation? Tbh I was hoping to avoid relations in my entity code, because I've seen quite a few problems arise from it on the mailinglist, but maybe I have no choice :-)
    • anything else?

    I hope I'm explaining this right. I think many have had to solve this. I think I'm just looking over some very standard Symfony functionality, just because I'm not sure what it's called :-)

    解决方案

    First, you should be using relationship - i.e. Machine has one monitory. I think people have problems with this because when you're used to thinking about things in terms of "id"s and foreign keys, thinking about relationships in a fully object-oriented way is new :).

    So, assuming your Machine is related to Monitor, you can now create a MachineType that embeds a MonitorType (which would be a form with the serialnumber field in it). Then, your constraints for serialnumber on your Monitor class would be used when the compound form is submitted.

    By default, when you bind all of this, it'll create a new Machine object, with a new Monitor object available via $machine->getMonitor(). If you persist, this will be two inserts. However, I'm guessing that you'd rather lookup the monitor by its serialnumber and use that existing monitor, right? To do so is easy, just short-circuit things after you bind your form.

    $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();
    
        // ...
    }
    

    So, that's the idea. Biggest thing is that by not using relationships, you're putting yourself at a disadvantage. You see, by embedding these two forms together, you really do have natural access to the serialnumber field.

    Good luck!

    这篇关于Symfony2形式,其中数据对象不完全匹配需要填写的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆