Answer the question
In order to leave comments, you need to log in
How to save a form that has a collection of another form embedded in it?
Hello! I've been struggling for a week now, I can not solve the problem, help someone with what they can)).
There are 2 tables:
1. Customers
2. Phone
The Customers table is related to the Phone table in a one-to-many relationship.
In accordance with the manual https://symfony.com/doc/3.4/form/form_collections.html
implemented embedding another form collection into my form.
The problem is that when saving the form, an error occurs when inserting a record into the associated table, because at the time of saving, Customer has not yet been created, and the Pnone table requires the client's customer_id:
An exception occurred while executing 'INSERT INTO phone (phone, description, customer_id) VALUES (?, ?, ?)' with params ["+7 (132) 143-24-12", "My note", null]:
SQLSTATE[23000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Cannot insert the value NULL into column 'customer_id', table 'CustomersBase.dbo.phone'; column does not allow nulls. INSERT fails.
How can this problem be solved? thank!
Below is the shortened code:
// src/AppBundle/Entity/Customers.php
/**
* Customers
*Заказчики
* @ORM\Table(name="Customers")
* @ORM\Entity(repositoryClass="AppBundle\Repository\CustomersRepository")
*/
class Customers implements UserInterface
{
/**
* @var integer
*
* @ORM\Column(name="CustomerID", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $customerid;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Phone", mappedBy="customer_id", cascade={"persist", "remove", "merge"})
*/
private $phone;
public function __construct()
{
$this->phone = new ArrayCollection(); //Создаем коллекцию телефонов (связанная таблица phone)
}
public function getPhone()
{
return $this->phone;
}
/**
* Get customerid
*
* @return integer
*/
public function getCustomerid()
{
return $this->customerid;
}
}
// src/AppBundle/Entity/Phone.php
**
* Phone
*
* @ORM\Table(name="phone", indexes={@ORM\Index(name="IDX_444F97DD9395C3F3", columns={"customer_id"})})
* @ORM\Entity
*/
class Phone
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \AppBundle\Entity\Customers
*
* @ORM\ManyToOne(targetEntity="Customers", inversedBy="customerid")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="customer_id", referencedColumnName="CustomerID")
* })
*/
private $customer_id;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return \AppBundle\Entity\Customers
*/
public function getCustomerId()
{
return $this->customer_id;
}
/**
* @param \AppBundle\Entity\Customers $customer
*/
public function setCustomerId(\AppBundle\Entity\Customers $customer)
{
$this->customer_id = $customer;
}
}
// src/AppBundle/Form/CustomerType.php
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//....
$builder
->add('phone',CollectionType::class, array(
'entry_type' => PhoneType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'entry_options' => array(
'required' => false,
'label' => false
)
));
//....
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Customers'
));
}
// src/AppBundle/Form/PhoneType.php
class PhoneType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('phone', null);
$builder->add('description', null);
$builder->add('customerId', HiddenType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Phone',
));
}
}
// src/AppBundle/Controller/CustomersController.php
class CustomersController extends Controller
{
public function indexAction(Request $request)
{
$customer = new Customers();
//Добавляем пустой телефон, чтобы отобразить его в форме
$phone = new Phone();
$customer->getPhone()->add($phone);
$form = $this->createForm('AppBundle\Form\CustomerType', $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($customer);
$em->flush();
}
}
}
Answer the question
In order to leave comments, you need to log in
Your link suggests a solution:
// src/AppBundle/Form/CustomerType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
//....
$builder
->add('phones',CollectionType::class, array(
'by_reference' => false,
// ...
));
//....
}
class Customers implements UserInterface
{
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Phone", mappedBy="customer_id", cascade={"persist", "remove", "merge"})
*/
private $phones; // Это же коллекция, нужно множественное число, чтобы работали adder и remover
public function addPhone(Phone $phone)
{
$phone->setCustomer($this);
$this->phones->add($phone);
}
public function removePhone(Phone $phone)
{
$phone->setCustomer(null);
$this->phones->removeElement($phone);
}
}
// src/AppBundle/Form/PhoneType.php
// $builder->add('customerId', HiddenType::class); // не нужен
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question