2017-01-02 44 views
1

我想存储一些数据嵌套CollectionType保存实体的ArrayCollection

class Offer 
{ 
    /** 
    * @ORM\Column(type="array") 
    */ 
    private $meterPoints; 


    public function __construct() 
    { 
     $this->meterPoints = new ArrayCollection(); 
    } 
} 

的报价为CollectionType。

class OfferType extends AbstractType 
{ 
    $builder 
     ->add('meterPoints', CollectionType::class, array(
      'entry_type' => OfferMeterPointType::class, 
      'allow_add' => true, 
      'allow_delete' => true, 
      'prototype' => true, 
      'prototype_name' => '__mp_name__', 
     )) 
} 

在OfferMeterPointType我也有一个的EntityType

class OfferMeterPointType extends AbstractType 
{ 
    $builder 
     ->add('meterPoint', EntityType::class, array(
      'attr' => array(
       'class' => 'chosen-select' 
      ), 
      'class' => 'AppBundle:MeterPoint', 
      'choice_label' => 'meterPoint', 
     )) 
     ->add('billData', CollectionType::class, array(
      'label' => false, 
      'entry_type' => OfferBillType::class, 
      'allow_add' => true, 
      'allow_delete' => true, 
      'entry_options' => array(
       'label' => false 
      ) 
     )); 

} 

现在,当我坚持认为实体整个的appbundle:MeterPoint对象获取序列化,而不仅仅是ID。我有点理解为什么教义这样做,但我可以改变它,只有ID将被存储?

此外,当我想编辑报价

$offer = $em->getRepository('AppBundle:Offer')->findOneById(2); 
$form = $this->createForm(OfferType::class, $offer); 

我得到一个异常

实体传递到选择现场必须加以管理。也许坚持他们在实体经理?

我想一个解决方案是为OfferMeterPointType创建一个实体,但我真的不想这样做。因为我几乎从不需要这些数据。

更新

我试着像马丁建议。现在异常走了,但它仍然保存完整的对象

$meterPoints = $this->em->getRepository('AppBundle:MeterPoint')->findAll(); 
    //dump($meterPoints); 
    $builder 
     ->add('meterPoint', ChoiceType::class, array(
      'label' => 'offerMeterPoint.meterPoint', 
      'attr' => array(
       'class' => 'chosen-selesct', 
       'placeholder' => 'ob.to' 
      ), 
      'choices' => $meterPoints, 
      'choice_label' => function($meterPoint) { 
       return $meterPoint->getMeterPoint(); 
      }, 
      'choice_value' => function($meterPoint) { 
       if($meterPoint === null){ 
        return null; 
       } 
       dump($meterPoint); 
       return $meterPoint->getId(); 
      }, 
      'placeholder' => 'global.plz_select' 
     )) 

更新2 得到它的工作 改变了ChoiceType

 $meterPoints = $this->em->getRepository('AppBundle:MeterPoint')->findAll(); 
    $mps = array(); 
    foreach($meterPoints as $mp){ 
     $mps [$mp->getMeterPoint()] = $mp->getId(); 
    } 
    //dump($meterPoints); 
    $builder 
     ->add('meterPoint', ChoiceType::class, array(
      'label' => 'offerMeterPoint.meterPoint', 
      'attr' => array(
       'class' => 'chosen-selesct', 
       'placeholder' => 'ob.to' 
      ), 
      'choices' => $mps, 
      'placeholder' => 'global.plz_select' 
     )) 

回答

0
  1. 你得到一个对象序列化,因为你的列类型是arrayEntityType自动用对象替换选项值。

    然而,choice_value也接受可调用,所以我会尝试摆弄它,也许你可以得到它只返回id(也许强制字符串类型?)。

    如果这没有帮助,那么可能只使用ChoiceType并自己处理逻辑。

  2. 发生这种情况是因为Doctrine会自动反序列化您尝试用作EntityType实体的$meterPoints中的对象。这些对象显然不是由Doctrine Entity manager管理的。因此错误。

    我想你必须将$meterPoints转换为数据库实体,然后才使用$this->createForm(...),如果你想避免创建更多的关系。最后,甚至更简单的方法将编写定制主义类型,可以为你做这个: