我已经symfony tutorial嵌入了一系列表单。一切都有效,除了现有的实体移除。
初始数据:
+----+-------+
| id | value |
+----+-------+
| 1 | a |
+----+-------+
| 2 | b |
+----+-------+
| 3 | c |
+----+-------+
然后在收集表单中,我删除a
值表单。提交和handleRequest()后,数据变为:
+----+-------+
| id | value |
+----+-------+
| 1 | b |
+----+-------+
| 2 | c |
+----+-------+
看起来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;
}
}