加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – Symfony表单不保存与ManyToMany关系的实体

发布时间:2020-12-13 15:56:07 所属栏目:PHP教程 来源:网络整理
导读:我有与ManyToMany关系保存实体槽形式的问题. 我无法保存关系“mappedBy”一侧的字段. 下面的代码不会将任何内容保存到数据库中,也不会丢失任何错误: // Entity/Pet/** * @var DoctrineCommonCollectionsCollection * * @ORMManyToMany(targetEntity="A
我有与ManyToMany关系保存实体槽形式的问题.

我无法保存关系“mappedBy”一侧的字段.

下面的代码不会将任何内容保存到数据库中,也不会丢失任何错误:

// Entity/Pet
/**
 * @var DoctrineCommonCollectionsCollection
 *
 * @ORMManyToMany(targetEntity="AppBundleEntityCustomer",mappedBy="pet",cascade={"persist"})
 */
private $customer;

/**
 * Set customer
 *
 * @param AppBundleEntityCustomer $customer
 * @return Pet
 */
public function setCustomer($customer)
{
    $this->customer = $customer;

    return $this;
}

// Entity/Customer
/**
 * @var Pet
 *
 * @ORMManyToMany(targetEntity="AppBundleEntityPet",inversedBy="customer",cascade={"persist"})
 * @ORMJoinTable(name="customer_pet",*   joinColumns={
 *     @ORMJoinColumn(name="customer_id",referencedColumnName="id")
 *   },*   inverseJoinColumns={
 *     @ORMJoinColumn(name="pet_id",referencedColumnName="id")
 *   }
 * )
 */
private $pet;

// PetType.php
$builder->add('customer','entity',array(
            'class' => 'AppBundle:Customer','property' => 'firstname','empty_value' => 'Choose owner','multiple' => true
          ));

它反过来工作.因此,如果我从CustomerType中保存一些东西,那么一切正常.

编辑:

下面的解决方案对我有用,但几天后我发现该解决方案存在问题.如果将使用已保存在数据库中的值提交表单,则Symfony将抛出错误.为了防止我必须检查给定的客户是否已经分配给宠物.

检查当前分配的客户必须在功能开始时而不是在表单提交之后完成,因为在提交之后由于某种原因,Pet()对象包含提交的值,而不仅仅是存在于db中的值.

所以一开始我把所有已经分配的客户都放到了阵列中

$em = $this->getDoctrine()->getManager();
  $pet = $em->getRepository('AppBundle:Pet')->find($id);
  $petOriginalOwners = array();
  foreach ($pet->getCustomer() as $petCustomer) 
  {
      $petOriginalOwners[] = $petCustomer->getId();
  }

在表单提交后,我检查了提交的ID是否在数组中

if ($form->isValid()) 
{
  foreach ($form['customer']->getData()->getValues() as $v) 
  {
    $customer = $em->getRepository('AppBundle:Customer')->find($v->getId());
    if ($customer && !in_array($v->getId(),$petOriginalOwners) )      
    {
      $customer->addPet($pet);
    }
  }
  $em->persist($pet);
  $em->flush();
  return $this->redirect($this->generateUrl('path'));
}

解决方法

在Symfony2中,具有withversedBy教义注释的属性的实体是应该编辑由MANYTOMANY RELATION创建的EXTRA TABLE的实体.这就是为什么当您创建客户时,它会在该额外表中插入相应的行,从而保存相应的宠物.

如果你想以相反的方式发生相同的行为,我建议:

//PetController.php
public function createAction(Request $request) {
    $entity = new Pet();
    $form = $this->createCreateForm($entity);
    $form->submit($request);



    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        foreach ($form['customer']->getData()->getValues() as $v) {
            $customer = $em->getRepository('AppBundle:Customer')->find($v->getId());
            if ($customer) {
                $customer->addPet($entity);
            }
        }
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('pet_show',array('id' => $entity->getId())));
    }

    return $this->render('AppBundle:pet:new.html.twig',array(
                'entity' => $entity,'form' => $form->createView(),));
}

private function createCreateForm(Pet $entity) {
        $form = $this->createForm(new PetType(),$entity,array(
            'action' => $this->generateUrl('pet_create'),'method' => 'POST',));

        return $form;
    }

这两个是控制器中与Pet实体对应的标准Symfony2 CRUD生成的操作.

唯一的调整是在第一个动作中插入的foreach结构,这样您就可以强制将相同的宠物添加到您在表单中选择的每个客户,从而获得所需的行为.

看,很有可能这不是正确的方式,或者是正确的方式,但是是一种方式而且它有效.希望能帮助到你.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读