2016-09-22 4 views
0

私はsymfony tutorialによってフォームのコレクションを埋め込みました。既存のエンティティの削除を除き、すべてが機能します。handleRequest()がスワップした後のフォームコレクションデータ

初期データ:

+----+-------+ 
| id | value | 
+----+-------+ 
| 1 | a  | 
+----+-------+ 
| 2 | b  | 
+----+-------+ 
| 3 | c  | 
+----+-------+ 

その後収集フォームで私はa値のフォームを削除します。 ()

+----+-------+ 
| id | value | 
+----+-------+ 
| 1 | b  | 
+----+-------+ 
| 2 | c  | 
+----+-------+ 

はのhandleRequestのように見えるだけで、配列のコレクション値をオーバーライドして、すべての差分を削除しています:提出とのhandleRequest()した後、データはなりました。期待される結果は次のようになります。

+----+-------+ 
| id | value | 
+----+-------+ 
| 2 | b  | 
+----+-------+ 
| 3 | c  | 
+----+-------+ 

そうですが、なぜでしょうか?

コントローラー:

public function indexAction(Request $request, Agreement $agreement) 
{ 
    $form = $this 
     ->createForm(CostGroupsCollectionType::class, $agreement) 
     ->add('submit', SubmitType::class, ['label' => 'button.save']); 
    $form->handleRequest($request); 

    if ($form->isValid()) { 
     $em = $this->getDoctrine()->getManager(); 
     $em->flush(); 

     return $this->redirectToRoute('team_agreements_cost_groups', ['id' => $agreement->getId()]); 
    } 

    return array(
     'form' => $form->createView(), 
     'agreement' => $agreement 
    ); 
} 

CostGroupsCollectionType:

class CostGroupsCollectionType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('costGroups', CollectionType::class, [ 
      'label' => false, 
      'entry_type' => CostGroupType::class, 
      'cascade_validation' => true, 
      'allow_add' => true, 
      'allow_delete' => true, 
      'prototype' => true, 
      'by_reference' => false, 
      'attr'   => array(
       'class' => 'form-collection', 
      ), 
     ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => 'Nfq\TeamBundle\Entity\Agreement', 
      'cascade_validation' => true 
     ]); 
    } 

    public function getName() 
    { 
     return 'nfq_team_bundle_cost_groups_collection_type'; 
    } 
} 

CostGroupType:

class CostGroupType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     /** @var EmployeeRepository $employeeRepo */ 
     $employeeRepo = $options['employeesRepo']; 

     $builder 
      ->add('costGroupPosition', EntityType::class, [ 
       'label' => 'teams.cost_group.title', 
       'class' => 'Nfq\TeamBundle\Entity\CostGroupPosition', 
       'attr' => ['class' => 'autocomplete'], 
       'choice_label' => 'title', 
       'multiple' => false, 
       'required' => true 
      ]) 
      ->add('price', NumberType::class, [ 
       'label' => 'teams.cost_group.price', 
       'required' => true 
      ]) 
      ->add('employees', EntityType::class, [ 
       'label' => 'teams.cost_group.employees', 
       'class'=> 'Nfq\ResourcesBundle\Entity\Employee', 
       'attr' => ['class' => 'autocomplete-unique'], 
       'choice_label' => function ($employee) { 
        /** @var Employee $employee */ 
        return $employee->getFullName(); 
       }, 
       'multiple' => true, 
       'required' => false 
      ]) 
      ->add('currency', EntityType::class, [ 
       'label' => 'currency.single_title', 
       'class' => Currency::class, 
       'choice_label' => function (Currency $c) { 
        return $c->getName(); 
       }, 
       'multiple' => false, 
       'expanded' => false, 
       'empty_data' => 'null', 
       'placeholder' => 'misc.selectAValue', 
       'required' => true 
      ]) 
      ->add('exchangeRate', NumberType::class, [ 
       'label' => 'teams.dedicated.invoices.details.exchange_rate', 
       'required' => true, 
      ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => 'Nfq\TeamBundle\Entity\CostGroup' 
     ]); 
    } 

    public function getName() 
    { 
     return 'nfq_team_bundle_cost_group_type'; 
    } 
} 

契約

class Agreement 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="title", type="string", length=255) 
    */ 
    private $title; 

    /** 
    * @ORM\ManyToOne(targetEntity="Nfq\ClientsBundle\Entity\Company", inversedBy="agreements") 
    * @ORM\JoinColumn(name="Company_id", referencedColumnName="id") 
    */ 
    private $client; 

    /** 
    * @ORM\ManyToOne(targetEntity="Nfq\ResourcesBundle\Entity\Team", inversedBy="agreements") 
    * @ORM\JoinColumn(name="Team_id", referencedColumnName="id") 
    */ 
    private $team; 

    /** 
    * @ORM\ManyToOne(targetEntity="Nfq\UserBundle\Entity\User", inversedBy="agreements") 
    * @ORM\JoinColumn(name="User_id", referencedColumnName="id") 
    */ 
    private $assignee; 

    /** 
    * @var \DateTime 
    * 
    * @ORM\Column(name="start_date", type="date") 
    */ 
    private $startDate; 

    /** 
    * @var \DateTime 
    * 
    * @ORM\Column(name="end_date", type="date", nullable=true) 
    */ 
    private $endDate; 

    /** 
    * @var bool 
    * 
    * @ORM\Column(name="ended", type="boolean") 
    */ 
    private $ended; 

    /** 
    * @ORM\OneToOne(targetEntity="Nfq\TeamBundle\Entity\Requisites", mappedBy="agreement") 
    */ 
    private $requisites; 

    /** 
    * @ORM\OneToMany(targetEntity="Nfq\TeamBundle\Entity\CostGroup", mappedBy="agreement", 
    *  cascade={"all"}, orphanRemoval=true) 
    */ 
    private $costGroups; 

    /** 
    * @ORM\OneToMany(targetEntity="Nfq\TeamBundle\Entity\DedicatedInvoice", mappedBy="agreement") 
    */ 
    private $dedicatedInvoices; 

    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->ended = false; 
     $this->costGroups = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->dedicatedInvoices = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** 
    * Get id. 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set title. 
    * 
    * @param string $title 
    * 
    * @return Agreement 
    */ 
    public function setTitle($title) 
    { 
     $this->title = $title; 

     return $this; 
    } 

    /** 
    * Get title. 
    * 
    * @return string 
    */ 
    public function getTitle() 
    { 
     return $this->title; 
    } 

    /** 
    * Set startDate. 
    * 
    * @param \DateTime $startDate 
    * 
    * @return Agreement 
    */ 
    public function setStartDate($startDate) 
    { 
     $this->startDate = $startDate; 

     return $this; 
    } 

    /** 
    * Get startDate. 
    * 
    * @return \DateTime 
    */ 
    public function getStartDate() 
    { 
     return $this->startDate; 
    } 

    /** 
    * Set endDate. 
    * 
    * @param \DateTime $endDate 
    * 
    * @return Agreement 
    */ 
    public function setEndDate($endDate) 
    { 
     $this->endDate = $endDate; 

     return $this; 
    } 

    /** 
    * Get endDate. 
    * 
    * @return \DateTime 
    */ 
    public function getEndDate() 
    { 
     return $this->endDate; 
    } 

    /** 
    * Set ended. 
    * 
    * @param boolean $ended 
    * 
    * @return Agreement 
    */ 
    public function setEnded($ended) 
    { 
     $this->ended = $ended; 

     return $this; 
    } 

    /** 
    * Get ended. 
    * 
    * @return boolean 
    */ 
    public function getEnded() 
    { 
     return $this->ended; 
    } 

    /** 
    * Set client. 
    * 
    * @param \Nfq\ClientsBundle\Entity\Company $client 
    * 
    * @return Agreement 
    */ 
    public function setClient(\Nfq\ClientsBundle\Entity\Company $client = null) 
    { 
     $this->client = $client; 

     return $this; 
    } 

    /** 
    * Get client. 
    * 
    * @return \Nfq\ClientsBundle\Entity\Company 
    */ 
    public function getClient() 
    { 
     return $this->client; 
    } 

    /** 
    * Set team. 
    * 
    * @param \Nfq\ResourcesBundle\Entity\Team $team 
    * 
    * @return Agreement 
    */ 
    public function setTeam(\Nfq\ResourcesBundle\Entity\Team $team = null) 
    { 
     $this->team = $team; 

     return $this; 
    } 

    /** 
    * Get team. 
    * 
    * @return \Nfq\ResourcesBundle\Entity\Team 
    */ 
    public function getTeam() 
    { 
     return $this->team; 
    } 

    /** 
    * Set assignee. 
    * 
    * @param User $assignee 
    * 
    * @return Agreement 
    */ 
    public function setAssignee(User $assignee = null) 
    { 
     $this->assignee = $assignee; 

     return $this; 
    } 

    /** 
    * Get assignee. 
    * 
    * @return User 
    */ 
    public function getAssignee() 
    { 
     return $this->assignee; 
    } 

    /** 
    * Set requisites. 
    * 
    * @param \Nfq\TeamBundle\Entity\Requisites $requisites 
    * 
    * @return Agreement 
    */ 
    public function setRequisites(\Nfq\TeamBundle\Entity\Requisites $requisites = null) 
    { 
     $this->requisites = $requisites; 

     return $this; 
    } 

    /** 
    * Get requisites. 
    * 
    * @return \Nfq\TeamBundle\Entity\Requisites 
    */ 
    public function getRequisites() 
    { 
     return $this->requisites; 
    } 

    /** 
    * Add costGroup. 
    * 
    * @param \Nfq\TeamBundle\Entity\CostGroup $costGroup 
    * 
    * @return Agreement 
    */ 
    public function addCostGroup(\Nfq\TeamBundle\Entity\CostGroup $costGroup) 
    { 
     if (!$this->costGroups->contains($costGroup)) { 
      $this->costGroups->add($costGroup); 
     } 
     $costGroup->setAgreement($this); 

     return $this; 
    } 

    /** 
    * Remove costGroup. 
    * 
    * @param \Nfq\TeamBundle\Entity\CostGroup $costGroup 
    */ 
    public function removeCostGroup(\Nfq\TeamBundle\Entity\CostGroup $costGroup) 
    { 
     if ($this->costGroups->contains($costGroup)) { 
      $this->costGroups->removeElement($costGroup); 
     } 
     $costGroup->setAgreement(null); 
    } 

    /** 
    * Get costGroups. 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getCostGroups() 
    { 
     return $this->costGroups; 
    } 

    /** 
    * Add dedicatedInvoice. 
    * 
    * @param \Nfq\TeamBundle\Entity\DedicatedInvoice $dedicatedInvoice 
    * 
    * @return Agreement 
    */ 
    public function addDedicatedInvoice(\Nfq\TeamBundle\Entity\DedicatedInvoice $dedicatedInvoice) 
    { 
     $this->dedicatedInvoices[] = $dedicatedInvoice; 

     return $this; 
    } 

    /** 
    * Remove dedicatedInvoice. 
    * 
    * @param \Nfq\TeamBundle\Entity\DedicatedInvoice $dedicatedInvoice 
    */ 
    public function removeDedicatedInvoice(\Nfq\TeamBundle\Entity\DedicatedInvoice $dedicatedInvoice) 
    { 
     $this->dedicatedInvoices->removeElement($dedicatedInvoice); 
    } 

    /** 
    * Get dedicatedInvoices. 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getDedicatedInvoices() 
    { 
     return $this->dedicatedInvoices; 
    } 
} 

CostGroup

class CostGroup 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var float 
    * 
    * @ORM\Column(name="price", type="decimal", precision=10, scale=2) 
    */ 
    private $price; 

    /** 
    * @ORM\ManyToOne(targetEntity="Nfq\TeamBundle\Entity\Agreement", inversedBy="costGroups") 
    * @ORM\JoinColumn(name="Agreement_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    private $agreement; 

    /** 
    * @ORM\ManyToOne(targetEntity="Nfq\TeamBundle\Entity\CostGroupPosition", inversedBy="costGroups") 
    * @ORM\JoinColumn(name="cost_group_position_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    private $costGroupPosition; 

    /** 
    * @ORM\ManyToMany(targetEntity="Nfq\ResourcesBundle\Entity\Employee", inversedBy="costGroups") 
    * @ORM\JoinTable(name="cost_group_employee") 
    */ 
    private $employees; 

    /** 
    * @ORM\OneToMany(targetEntity="Nfq\TeamBundle\Entity\DedicatedEmployees", mappedBy="costGroup") 
    */ 
    private $dedicatedEmployees; 

    /** 
    * @var float 
    * @ORM\Column(name="exchange_rate", type="float", nullable=true) 
    */ 
    private $exchangeRate; 

    /** 
    * @var Currency 
    * @ORM\ManyToOne(targetEntity="Nfq\SettingsBundle\Entity\Currency", inversedBy="costGroups") 
    * @ORM\JoinColumn(name="Currency_id", referencedColumnName="id") 
    */ 
    private $currency; 

    /** 
    * Constructor. 
    */ 
    public function __construct() 
    { 
     $this->employees = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->dedicatedEmployees = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->exchangeRate = 1; 
    } 

    /** 
    * Get id. 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set price. 
    * 
    * @param string $price 
    * 
    * @return CostGroup 
    */ 
    public function setPrice($price) 
    { 
     $this->price = $price; 

     return $this; 
    } 

    /** 
    * Get price. 
    * 
    * @return string 
    */ 
    public function getPrice() 
    { 
     return $this->price; 
    } 

    /** 
    * Set agreement. 
    * 
    * @param \Nfq\TeamBundle\Entity\Agreement $agreement 
    * 
    * @return CostGroup 
    */ 
    public function setAgreement(\Nfq\TeamBundle\Entity\Agreement $agreement = null) 
    { 
     $this->agreement = $agreement; 

     return $this; 
    } 

    /** 
    * Get agreement. 
    * 
    * @return \Nfq\TeamBundle\Entity\Agreement 
    */ 
    public function getAgreement() 
    { 
     return $this->agreement; 
    } 

    /** 
    * Set costGroupPosition. 
    * 
    * @param \Nfq\TeamBundle\Entity\CostGroupPosition $costGroupPosition 
    * 
    * @return CostGroup 
    */ 
    public function setCostGroupPosition(\Nfq\TeamBundle\Entity\CostGroupPosition $costGroupPosition = null) 
    { 
     $this->costGroupPosition = $costGroupPosition; 

     return $this; 
    } 

    /** 
    * Get costGroupPosition. 
    * 
    * @return \Nfq\TeamBundle\Entity\CostGroupPosition 
    */ 
    public function getCostGroupPosition() 
    { 
     return $this->costGroupPosition; 
    } 

    /** 
    * Add employee. 
    * 
    * @param \Nfq\ResourcesBundle\Entity\Employee $employee 
    * 
    * @return CostGroup 
    */ 
    public function addEmployee(\Nfq\ResourcesBundle\Entity\Employee $employee) 
    { 
     $this->employees[] = $employee; 

     return $this; 
    } 

    /** 
    * Remove employee. 
    * 
    * @param \Nfq\ResourcesBundle\Entity\Employee $employee 
    */ 
    public function removeEmployee(\Nfq\ResourcesBundle\Entity\Employee $employee) 
    { 
     $this->employees->removeElement($employee); 
    } 

    /** 
    * Get employees. 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getEmployees() 
    { 
     return $this->employees; 
    } 

    /** 
    * Add dedicatedEmployee. 
    * 
    * @param \Nfq\TeamBundle\Entity\DedicatedEmployees $dedicatedEmployee 
    * 
    * @return CostGroup 
    */ 
    public function addDedicatedEmployee(\Nfq\TeamBundle\Entity\DedicatedEmployees $dedicatedEmployee) 
    { 
     $this->dedicatedEmployees[] = $dedicatedEmployee; 

     return $this; 
    } 

    /** 
    * Remove dedicatedEmployee. 
    * 
    * @param \Nfq\TeamBundle\Entity\DedicatedEmployees $dedicatedEmployee 
    */ 
    public function removeDedicatedEmployee(\Nfq\TeamBundle\Entity\DedicatedEmployees $dedicatedEmployee) 
    { 
     $this->dedicatedEmployees->removeElement($dedicatedEmployee); 
    } 

    /** 
    * Get dedicatedEmployees. 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getDedicatedEmployees() 
    { 
     return $this->dedicatedEmployees; 
    } 

    /** 
    * Set exchangeRate. 
    * 
    * @param float $exchangeRate 
    * 
    * @return CostGroup 
    */ 
    public function setExchangeRate($exchangeRate) 
    { 
     $this->exchangeRate = $exchangeRate; 

     return $this; 
    } 

    /** 
    * Get exchangeRate. 
    * 
    * @return float 
    */ 
    public function getExchangeRate() 
    { 
     return $this->exchangeRate; 
    } 

    /** 
    * Set currency. 
    * 
    * @param Currency $currency 
    * 
    * @return CostGroup 
    */ 
    public function setCurrency(Currency $currency = null) 
    { 
     $this->currency = $currency; 

     return $this; 
    } 

    /** 
    * Get currency. 
    * 
    * @return Currency 
    */ 
    public function getCurrency() 
    { 
     return $this->currency; 
    } 
} 
+0

'Nfq \ TeamBundle \ Entity \ Agreement'宣言を提供できますか?ここではすべてが有効です。 –

+0

@DmitryMalyshenkoがAgreementおよびCostGroupエンティティ宣言で更新しました – rokas

答えて

1

は正しく教義であるArrayCollectionの永続化を処理するための方法をthe documentationを参照してください。

+0

既に試してみました。隠されたidを追加し、フォームを提出した後 'PropertyAccessor' throws'プロパティ "id"と "addId()"/"removeId()"、 "setId()"、 "id()"、 "__set( ) "または" __call() "が存在し、" Nfq \ TeamBundle \ Entity \ CostGroup "クラスのパブリックアクセスを持っています。また、setId()を追加しようとしましたが、問題は残ります。 – rokas

+0

実際には、それを処理する方法を説明する公式のsymfonyのドキュメントがあることを思い出しました。だから私は私の答えを変更しました。 –

+0

問題が見つかりました。私は(jsクラスで)項目を追加/削除した後にフォームIDを再索引していました。それで、配列のキーを要求するのは、handleRequestの後のエンティティと正しく一致しません。 – rokas

関連する問題