如何在 symfony 中将数据插入两个 table 具有单一表单类型?
How to insert data into two table have a single form type in symfony?
我有一个表格可以在以下 table:
中插入数据
供应商
- first_name
- last_name
- 地址
地址
- 地址
- 城市
- 状态
- 密码
- 国家
注意:
我没有在供应商 table 中创建地址作为 FK,但它确实保存了地址 table 的 ID。
我参考文档做了这个表格class:
https://symfony.com/doc/current/form/embedded.html
VendorType 表单 class:
class VendorType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('first_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter First name',
]
])
->add('last_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter Last name'
]
])
->add('address',TextAreaType::class,[
'attr' => [
'placeholder' => 'Enter your current address'
],
'mapped' => false,
//if given then value wont be fetched for address in entity object.
])
->add('city',TextType::class,[
'attr' => [
'placeholder' => 'Enter city'
]
])
->add('state',TextType::class,[
'attr' => [
'placeholder' => 'Enter state'
]
])
->add('country',TextType::class,[
'attr' => [
'placeholder' => 'Enter country'
]
])
->add('pincode',TextType::class,[
'attr' => [
'placeholder' => 'Enter Pincode'
]
])
->add('Save',SubmitType::class,[
'attr' => [
'class' => 'btn btn-success'
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Vendor::class,
]);
}
Controller:
$vendor = new Vendor();
$manager = $this->getDoctrine()->getManager();
$vendorForm = $this->createForm(VendorType::class, $vendor);
$vendorForm->handleRequest($request);
if ($vendorForm->isSubmitted()) {
if ($vendorForm->isValid()) {
$address = new Address;
$address->setAddress($request->request->get('vendor')['address']);
$address->setCity($request->request->get('vendor')['city']);
$address->setState($request->request->get('vendor')['state']);
$address->setCountry($request->request->get('vendor')['country']);
$address->setPincode($request->request->get('vendor')['pincode']);
$manager->persist($address);
$manager->flush();
if(null != $address->getId()){
$vendor->setFirstName($request->request->get('vendor')['first_name']);
$vendor->setLastName($request->request->get('vendor')['last_name']);
$vendor->setAddress($address->getId());
// dump($ven);
// die('uygyu');
$manager->persist($vendor);
$manager->flush();
$this->addFlash('success', 'Article Created! Knowledge is power!');
}
}
注:
在地址 table 中插入成功,但由于以下错误,数据未插入供应商 table。
错误信息:
执行 'INSERT INTO vendor (first_name, last_name, address, city, state, country, pincode) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["miss", "Negi", 62, null, null, null, null] 时发生异常:
SQLSTATE[42S22]:未找到列:1054 'field list'
中的未知列 'city'
如何将我的表单数据提交到各自的 table 中?
编辑:我知道供应商对象具有所有属性,因此它无法执行查询。我想知道这种情况如何解决?这里还能做什么?有没有更好的方法来保存这种形式?
地址实体:
namespace App\Entity;
/**
* @ORM\Entity(repositoryClass="App\Repository\AddressRepository")
*/
class Address
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text")
*/
private $address;
/**
* @ORM\Column(type="string", length=255)
*/
private $city;
/**
* @ORM\Column(type="string", length=255)
*/
private $state;
/**
* @ORM\Column(type="string", length=255)
*/
private $country;
/**
* @ORM\Column(type="integer")
*/
private $pincode;
/**
* @ORM\Column(type="string", length=255)
*/
private $address_type;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Customer", mappedBy="address")
*/
private $customers;
public function __construct()
{
$this->customers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(string $address): self
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getState(): ?string
{
return $this->state;
}
public function setState(string $state): self
{
$this->state = $state;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getPincode(): ?int
{
return $this->pincode;
}
public function setPincode(int $pincode): self
{
$this->pincode = $pincode;
return $this;
}
public function getAddressType(): ?string
{
return $this->address_type;
}
public function setAddressType(string $address_type): self
{
$this->address_type = $address_type;
return $this;
}
/**
* @return Collection|Customer[]
*/
public function getCustomers(): Collection
{
return $this->customers;
}
public function addCustomer(Customer $customer): self
{
if (!$this->customers->contains($customer)) {
$this->customers[] = $customer;
$customer->setAddress($this);
}
return $this;
}
public function removeCustomer(Customer $customer): self
{
if ($this->customers->contains($customer)) {
$this->customers->removeElement($customer);
// set the owning side to null (unless already changed)
if ($customer->getAddress() === $this) {
$customer->setAddress(null);
}
}
return $this;
}
}
供应商实体:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\VendorRepository")
*/
class Vendor
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $first_name;
/**
* @ORM\Column(type="string", length=255)
*/
private $last_name;
/**
* @ORM\Column(type="integer")
*/
private $address;
/**
* @ORM\Column(type="string", length=255)
*/
public $city;
/**
* @ORM\Column(type="string", length=255)
*/
public $state;
/**
* @ORM\Column(type="string", length=255)
*/
public $country;
/**
* @ORM\Column(type="integer", length=255)
*/
public $pincode;
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->first_name;
}
public function setFirstName(string $first_name): self
{
$this->first_name = $first_name;
return $this;
}
public function getLastName(): ?string
{
return $this->last_name;
}
public function setLastName(string $last_name): self
{
$this->last_name = $last_name;
return $this;
}
public function getAddress(): ?int
{
return $this->address;
}
public function setAddress(int $address): self
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function getState(): ?string
{
return $this->state;
}
public function getCountry(): ?string
{
return $this->country;
}
public function getPincode(): ?int
{
return $this->pincode;
}
}
Error message: An exception occurred while executing 'INSERT INTO vendor (first_name, last_name, address, city, state, country, pincode) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["miss", "Negi", 62, null, null, null, null]
检查你的 Getters 和 Setters。在这种情况下,您没有 setter 城市 属性 (以及更多)。这就是 Symfony 无法在 bbdd 中插入这些属性的原因。
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getState(): ?string
{
return $this->state;
}
public function setState(string $state): self
{
$this->state = $state;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getPincode(): ?int
{
return $this->pincode;
}
public function setPincode(int $pincode): self
{
$this->pincode = $pincode;
return $this;
}
还有一件事。您在 ventor 实体中的 pincode 的 ORM 注释中有错误。它是 int 并且您正在指定字符串的长度。
/**
* @ORM\Column(type="integer", length=255)
*/
public $pincode;
正如我们在提供的屏幕截图中看到的,Vendor table 中只有三个字段。有一个简单的错误,class 形式没有正确嵌入,这不是将一种形式嵌入到另一种形式的方法。
这个概念是创建 2 种不同的形式并将一种嵌入另一种。这里我们将 AddressType 形式 class 嵌入到 VendorType 形式 class.
VendorType 形式 class:
class VendorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('first_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter First name',
]
])
->add('last_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter Last name'
]
])
//Embeding AddressType form in VendorType form.
->add('address', AddressType::class)
->add('Save',SubmitType::class,[
'attr' => [
'class' => 'btn btn-success'
]
])
;
}
注意:在上面的代码中查找注释。
供应商
- first_name
- last_name
- 地址
地址
- 地址
- 城市
- 状态
- 密码
- 国家
注意: 我没有在供应商 table 中创建地址作为 FK,但它确实保存了地址 table 的 ID。
我参考文档做了这个表格class: https://symfony.com/doc/current/form/embedded.html
VendorType 表单 class:
class VendorType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('first_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter First name',
]
])
->add('last_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter Last name'
]
])
->add('address',TextAreaType::class,[
'attr' => [
'placeholder' => 'Enter your current address'
],
'mapped' => false,
//if given then value wont be fetched for address in entity object.
])
->add('city',TextType::class,[
'attr' => [
'placeholder' => 'Enter city'
]
])
->add('state',TextType::class,[
'attr' => [
'placeholder' => 'Enter state'
]
])
->add('country',TextType::class,[
'attr' => [
'placeholder' => 'Enter country'
]
])
->add('pincode',TextType::class,[
'attr' => [
'placeholder' => 'Enter Pincode'
]
])
->add('Save',SubmitType::class,[
'attr' => [
'class' => 'btn btn-success'
]
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Vendor::class,
]);
}
Controller:
$vendor = new Vendor();
$manager = $this->getDoctrine()->getManager();
$vendorForm = $this->createForm(VendorType::class, $vendor);
$vendorForm->handleRequest($request);
if ($vendorForm->isSubmitted()) {
if ($vendorForm->isValid()) {
$address = new Address;
$address->setAddress($request->request->get('vendor')['address']);
$address->setCity($request->request->get('vendor')['city']);
$address->setState($request->request->get('vendor')['state']);
$address->setCountry($request->request->get('vendor')['country']);
$address->setPincode($request->request->get('vendor')['pincode']);
$manager->persist($address);
$manager->flush();
if(null != $address->getId()){
$vendor->setFirstName($request->request->get('vendor')['first_name']);
$vendor->setLastName($request->request->get('vendor')['last_name']);
$vendor->setAddress($address->getId());
// dump($ven);
// die('uygyu');
$manager->persist($vendor);
$manager->flush();
$this->addFlash('success', 'Article Created! Knowledge is power!');
}
}
注: 在地址 table 中插入成功,但由于以下错误,数据未插入供应商 table。
错误信息: 执行 'INSERT INTO vendor (first_name, last_name, address, city, state, country, pincode) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["miss", "Negi", 62, null, null, null, null] 时发生异常:
SQLSTATE[42S22]:未找到列:1054 'field list'
中的未知列 'city'如何将我的表单数据提交到各自的 table 中?
编辑:我知道供应商对象具有所有属性,因此它无法执行查询。我想知道这种情况如何解决?这里还能做什么?有没有更好的方法来保存这种形式?
地址实体:
namespace App\Entity;
/**
* @ORM\Entity(repositoryClass="App\Repository\AddressRepository")
*/
class Address
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text")
*/
private $address;
/**
* @ORM\Column(type="string", length=255)
*/
private $city;
/**
* @ORM\Column(type="string", length=255)
*/
private $state;
/**
* @ORM\Column(type="string", length=255)
*/
private $country;
/**
* @ORM\Column(type="integer")
*/
private $pincode;
/**
* @ORM\Column(type="string", length=255)
*/
private $address_type;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Customer", mappedBy="address")
*/
private $customers;
public function __construct()
{
$this->customers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(string $address): self
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getState(): ?string
{
return $this->state;
}
public function setState(string $state): self
{
$this->state = $state;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getPincode(): ?int
{
return $this->pincode;
}
public function setPincode(int $pincode): self
{
$this->pincode = $pincode;
return $this;
}
public function getAddressType(): ?string
{
return $this->address_type;
}
public function setAddressType(string $address_type): self
{
$this->address_type = $address_type;
return $this;
}
/**
* @return Collection|Customer[]
*/
public function getCustomers(): Collection
{
return $this->customers;
}
public function addCustomer(Customer $customer): self
{
if (!$this->customers->contains($customer)) {
$this->customers[] = $customer;
$customer->setAddress($this);
}
return $this;
}
public function removeCustomer(Customer $customer): self
{
if ($this->customers->contains($customer)) {
$this->customers->removeElement($customer);
// set the owning side to null (unless already changed)
if ($customer->getAddress() === $this) {
$customer->setAddress(null);
}
}
return $this;
}
}
供应商实体:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\VendorRepository")
*/
class Vendor
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $first_name;
/**
* @ORM\Column(type="string", length=255)
*/
private $last_name;
/**
* @ORM\Column(type="integer")
*/
private $address;
/**
* @ORM\Column(type="string", length=255)
*/
public $city;
/**
* @ORM\Column(type="string", length=255)
*/
public $state;
/**
* @ORM\Column(type="string", length=255)
*/
public $country;
/**
* @ORM\Column(type="integer", length=255)
*/
public $pincode;
public function getId(): ?int
{
return $this->id;
}
public function getFirstName(): ?string
{
return $this->first_name;
}
public function setFirstName(string $first_name): self
{
$this->first_name = $first_name;
return $this;
}
public function getLastName(): ?string
{
return $this->last_name;
}
public function setLastName(string $last_name): self
{
$this->last_name = $last_name;
return $this;
}
public function getAddress(): ?int
{
return $this->address;
}
public function setAddress(int $address): self
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function getState(): ?string
{
return $this->state;
}
public function getCountry(): ?string
{
return $this->country;
}
public function getPincode(): ?int
{
return $this->pincode;
}
}
Error message: An exception occurred while executing 'INSERT INTO vendor (first_name, last_name, address, city, state, country, pincode) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["miss", "Negi", 62, null, null, null, null]
检查你的 Getters 和 Setters。在这种情况下,您没有 setter 城市 属性 (以及更多)。这就是 Symfony 无法在 bbdd 中插入这些属性的原因。
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city): self
{
$this->city = $city;
return $this;
}
public function getState(): ?string
{
return $this->state;
}
public function setState(string $state): self
{
$this->state = $state;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country): self
{
$this->country = $country;
return $this;
}
public function getPincode(): ?int
{
return $this->pincode;
}
public function setPincode(int $pincode): self
{
$this->pincode = $pincode;
return $this;
}
还有一件事。您在 ventor 实体中的 pincode 的 ORM 注释中有错误。它是 int 并且您正在指定字符串的长度。
/**
* @ORM\Column(type="integer", length=255)
*/
public $pincode;
正如我们在提供的屏幕截图中看到的,Vendor table 中只有三个字段。有一个简单的错误,class 形式没有正确嵌入,这不是将一种形式嵌入到另一种形式的方法。 这个概念是创建 2 种不同的形式并将一种嵌入另一种。这里我们将 AddressType 形式 class 嵌入到 VendorType 形式 class.
VendorType 形式 class:
class VendorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('first_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter First name',
]
])
->add('last_name',TextType::class,[
'attr' => [
'placeholder' => 'Enter Last name'
]
])
//Embeding AddressType form in VendorType form.
->add('address', AddressType::class)
->add('Save',SubmitType::class,[
'attr' => [
'class' => 'btn btn-success'
]
])
;
}
注意:在上面的代码中查找注释。