我有一个表格,用户填写了姓名。基于该名称,我在数据库上执行AJAX请求以了解是否有人使用该名称。如果存在,我将显示完整的表单,其中的输入将填充数据库中的数据。否则,我会显示一个空的完整表格。 在提交时,如果数据已经存在于数据库中,我想更新它们,但如果不是,则需要插入这些数据。插入新数据可以正常工作。
这是我的控制器功能,该功能链接到表单提交:
/**
*@Route("adherent/new", name="adherent_new")
*/
public function new(Request $request)
{
$adherent = new Adherent();
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(AdherentType::class, $adherent);
$form->handleRequest($request);
$produitRepository = $em->getRepository(Produit::class);
$allProduit = $produitRepository->findAll();
if($form->isSubmitted() && $form->isValid()){
$id = $request->request->get('id');
//if id exists then update
//otherwise create a new entry
$adherent = $form->getData();
$em->persist($adherent);
$em -> flush();
return $this->redirectToRoute('adherent_accueil');
}
return $this->render('adherent/new.html.twig', [
'form' => $form->createView(),
'produits' => $allProduit
]);
}
是否可以使用Symfony处理此问题?还是我必须手动执行此操作?
谢谢!
答案 0 :(得分:0)
代替创建新的$ adherent,您可以从数据库中加载特定的粘附者。像在documentation中一样手动操作,但是您可以使用Automatically Fetching Objects (ParamConverter),它非常干净:
composer require sensio/framework-extra-bundle
// src/Controller/ProductController.php
use App\Entity\Product;
/**
* @Route("/product/{id}", name="product_show")
*/
public function show(Product $product)
{
// use the Product!
// ...
}
然后,当您使用$ adherent创建表单时,该表单现在是具有数据库信息的对象: $ form = $ this-> createForm(AdherentType :: class,$ adherent);
它将自动用相应的数据填充表单字段。
我不是symfony的专业人士,但我使用了there。如果我理解得很好,请看一下路由“ / terminal / create”和“ / terminal / {id} / edit”,它似乎与您要实现的目标相似。
编辑
如果在发送到数据库之前设置对象的ID,它将更新您的粘附者;如果没有ID,它将创建一个新的粘附者。我认为您只需添加:
if($id){
$adherent->setId($id);
}
编辑
在您的代码中重新读取$ adherent = $ form-> getData();如果ID属于您的表单,则可能已经设置了对象的id。这意味着它应该已经可以按您期望的方式工作(如果在表单上设置了id,则更新粘附者;如果id为空,则创建粘附者)。如果没有,您可以输入您实体的代码和格式吗?
答案 1 :(得分:0)
好的,我明白你的意思了。我在依从类中没有id属性,因为它扩展了具有id的超类抽象类Demandeur。因此,在我的ckettendType表单中,我没有在其中添加id属性,而是将其直接添加到html模板中。这就解释了为什么我尝试使用
进行获取$id = $request->request->get('id');
因为我尝试使用getData(),并且由于我的实体Adherent没有id属性,所以setId()方法不存在,所以出现了异常:
Could not determine access type for property "id" in class "App\Entity\Adherent": Neither the property "id" nor one of the methods "addId()"/"removeId()", "setId()", "id()", "__set()" or "__call()" exist and have public access in class "App\Entity\Adherent".
是真的。在此之前,我尝试了add函数,一切正常,id和关系。
class AdherentType extends AbstractType
{
/**
*{@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', IntegerType::class)
->add('nom', TextType::class, [
'constraints' => [
new NotBlank(),
new Length(['max'=>50]),
]
])
->add('prenom', TextType::class, [
'constraints' => [
new NotBlank(),
new Length(['max'=>50]),
]
])
->add('numSocietaire', IntegerType::class, [
'constraints' => [
new NotBlank(),
new Length(['max'=>30]),
]
])
->add('anciennete', IntegerType::class, [
'required' => 'false',
])
->add('contratActif', IntegerType::class, [
'required' => 'false',
])
->add('dateNaiss', DateType::class, [
'widget' => 'single_text',
'required' => 'false',
])
->add('dateAdhes', DateType::class,[
'widget' => 'single_text',
'required' => 'false',
'empty_data' => '',
])
->add('datePremMut', DateType::class, [
'widget' => 'single_text',
'required' => 'false',
])
->add('nbBenef', IntegerType::class, [
'required' => 'false',
])
->add('nbIncidPaimt', IntegerType::class, [
'required' => 'false',
])
->add('detailContrat', DetailContratType::class)
->add('formule', EntityType::class, [
'class' => Formule::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.libelle', 'ASC');
},
'choice_label' => 'libelle',
'required' => 'false',
])
->add('ancienneFormule', TextType::class, [
'required' => 'false',
])
->add('resiliation', ResiliationType::class)
->add('save', SubmitType::class, ['label' => 'Créer l\'adhérent']);
}
我只是尝试在我的依附表单中添加一个具有id属性的Demandeur(超类)表单,但这是Adherent和Demandeur之间的继承,而不是关系。
class DemandeurType extends AbstractType
{
/**
*{@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', IntegerType::class);
}
}
class AdherentType extends AbstractType
{
/**
*{@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('demandeur', EntityType::class, [
'class' => Demandeur::class
])
....
}
}
有些事情我不了解,因为它没有按照我认为的方式工作...
编辑: 我已经添加了
parent::buildForm($builder, $options);
在我的粘附类型类中,我不再有任何错误,但仍然不想更新任何内容,只需添加...
编辑:我设法使它正常工作!因此,我提出了解决方案,以防某天有人对它感兴趣! 我在EventListener文件夹中创建一个UpdateDemandeur.php文件。我将函数preUpdate放到了epty中,因为在更新之前不需要在Demandeur表上进行任何操作。 棘手的部分是在我的控制器中。因为我没有向表单发送任何对象,所以在提交表单时,如果由于实体管理器而使用setId($ id)函数,那么我得到的对象就不属于Symfony事件。我不得不使用合并功能。这是我正在使用的代码,它正在工作。
if($request->isMethod('POST')){
foreach($forms as $form){
$form->handleRequest($request);
if( !$form->isSubmitted()) continue;
if($form->isValid()){
$demandeur = $form->getData();
$id = $request->request->get($type)['id'];
if($id > 0) {
$demandeur->setId($id);
//Need to merge the new demandeur Object filled
//with data from the form to update it in database
$dem = $em->merge($demandeur);
} else {
$em->persist($demandeur);
}
$em->flush();
return $this->redirectToRoute('demandeur_add');
}
}
}
希望它将对某人有所帮助!