尝试更新实体,并提交值不变的字段会导致类型错误。我在做什么错了?
实体:
<?php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
...
class User implements UserInterface
{
...
/**
* @ORM\Column(type="bigint", nullable=true)
* @Groups({"default", "listing"})
* @Assert\Type("integer")
*/
private $recordQuota;
...
FormType:
<?php
namespace App\Form;
...
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
...
->add('recordQuota', IntegerType::class)
;
}
...
}
控制器:
...
/**
* @Route("/api/user/{id}", name="editUser")
* @Method({"PUT", "PATCH"})
* @Rest\View()
*/
public function updateAction(Request $request, User $user)
{
$form = $this->createForm(UserType::class, $user);
$data = $request->request->get('user');
$clearMissing = $request->getMethod() != 'PATCH';
$form->submit($data, $clearMissing);
if ($form->isSubmitted() && $form->isValid()) {
...
我正在使用PostMan提交表单数据。 如果我要更新的实体的recordQuota为1000,那么我将提交具有不同值的表单。一切都能正常工作和更新。
但是,如果我使用recordQuota:1000提交表单,则该值应保持不变,我将得到一个错误的类型错误:
"recordQuota": {
"errors": [
"This value should be of type integer."
]
}
其他信息:
我使用$form->submit
而不是handleRequest
,因为我使用的是补丁程序。因此,我需要能够启用/禁用$clearMissing
。但是,即使使用handleRequest
也会产生相同的问题。
即使在将recordQuota传递给表单之前,将它的类型转换为int仍然失败。
如果我从窗体和实体中删除了所有类型信息,则在实际进行更改时会收到“此值应为字符串类型”。
答案 0 :(得分:0)
编辑:请注意,如果字段类型为TextType
,则以下内容是正确的,但是IntegerType
与@Assert\Type("integer")
可以正常工作。哪种会使我的答案无效/不相关...
您正在使用@Assert\Type("integer")
批注,但这意味着:
is_int($value)
string
您需要的是@Assert\Type("numeric")
:
is_numeric($value)
答案 1 :(得分:0)
这是与此处所述的Symfony 4.3验证程序auto_mapping结合使用的问题: https://symfony.com/blog/new-in-symfony-4-3-automatic-validation
制造商捆绑包将错误的类型转换添加到bigint字段。
请参阅此处: https://github.com/symfony/maker-bundle/issues/429
答案是将实体中的获取器和设置器更改为:
public function getRecordQuota(): ?int
{
return $this->recordQuota;
}
public function setRecordQuota(?int $recordQuota): self
{
$this->recordQuota = $recordQuota;
return $this;
}
到
public function getRecordQuota(): ?string
{
return $this->recordQuota;
}
public function setRecordQuota(?string $recordQuota): self
{
$this->recordQuota = $recordQuota;
return $this;
}
或者,可以在验证器配置中关闭auto_mapping。