简体   繁体   English

在 Symfony 2 / Doctrine 2 中更新实体一对多关系的最佳方法

[英]Best way to update entity one to many relationship in Symfony 2 / Doctrine 2

What is the best way to update an entities one to many relationship in doctine?在 doctine 中更新实体一对多关系的最佳方法是什么? For example: I have an entity called booking with a mapped one to many Guest entities.例如:我有一个名为 booking 的实体,它映射了一对多的 Guest 实体。

When a booking is edited, the number of guests can change by either adding or removing guests.编辑预订时,可以通过添加或删除客人来更改客人的数量。 At the moment, I count the number of guests submitted, and if they are different to the current number of guests, i delete the booking guests and re add the new ones目前,我统计提交的客人数量,如果与当前客人数量不同,我删除预订客人并重新添加新客人

To me this doesn't seem right and would like to know how other people approach this.对我来说,这似乎不对,我想知道其他人如何处理这个问题。

Code example:代码示例:

    if (count($collection)) {
        $numberGuests = count($this->getEntity()->getGuests());
        foreach ($collection as $guest) {
            if ($numberGuests != count($guests)) {
                // delete guest if the number has changed
                $this->getGuestManager()->delete($guest);
            } else {
                // update entity
                $guest->setArrayData(Tools::getData($i, $guests));
            }
        }
    }

I don't think there is a best way, but the way you have now is not correct.我认为没有最好的方法,但是您现在的方法不正确。 Why if the user modifies the guests but the number is still the same (he deletes one guest from the list but adds a new one)?为什么如果用户修改了客人,但人数仍然相同(他从列表中删除了一位客人,但添加了一位新客人)?

Anyway, I don't think it's a bad approach to "Reset" the relationship everytime somebody edits (maybe not the most efficient though) you will just need to set, from the owning side (guest), the booking.无论如何,我认为每次有人编辑时“重置”关系并不是一个糟糕的方法(尽管可能不是最有效的),您只需要从拥有方(客人)设置预订。 (In a many to one relationship, the "many" side has to be the owning side) (在多对一关系中,“多”方必须是拥有方)

I would do that in controler:我会在控制器中这样做:

    if ($editForm->isValid()) {

        //find all guests entities that has this booking related
        $oldguests=$em->getRepository('YourBundle:Guest')->findby(array("booking"=>$entity));
        //well you will need to custom a little bit better this "findby"

        foreach($oldguest as $guest){
             //remove the booking for that guest. So that guest won't have any booking linked  
             $guest->removeBooking();
             $em->persist($guest);  
        }
        //now we make the link with guest and booking 
        //$form->submit($request) should have set the current entity with the current guests the user selected
        foreach($entity->getGuests() as $currentguest){
             $currentguest->setBooking($entity);
             $em->persist($guest);
        }

        $em->persist($entity);
        $em->flush();

    }

And in the Guests entity I would add the function removeUser在来宾实体中,我将添加 function removeUser

 //guest.php
 public function removeBooking(){
       $this->booking=NULL;
 } 

Maybe is more elegant if you create a function in the GuestRepository.php that does what the controller is doing, and in the controller you just call that function. Maybe is more elegant if you create a function in the GuestRepository.php that does what the controller is doing, and in the controller you just call that function.

You really need to take care of the owning side of the relationship.你真的需要照顾关系的拥有方。 If you allow the edition through the owning side, that is, updating guests with the booking, the default code app/console gives you wouldn't need any kind of customization at all: both entities would be properly updated.如果您通过拥有方允许版本,即使用预订更新客人,则默认代码应用程序/控制台为您提供根本不需要任何类型的自定义:两个实体都将正确更新。

To keep it simple we can say that: let the user update the owning side of the relationship => everything is automatic.为了简单起见,我们可以说:让用户更新关系的拥有方 => 一切都是自动的。 Let the user update the inverse side of the relationship => manual customization required.让用户更新关系的反面 => 需要手动定制。 (this is the same for many to many relationships). (这对于多对多关系也是一样的)。

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM