3

尝试更新实体并提交具有未更改值的字段会导致类型错误。我究竟做错了什么?

实体:

<?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;

...

表格类型:

<?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 仍然失败。

如果我从表单和实体中删除所有类型信息,我会在实际进行更改时得到“这个值应该是字符串类型”。

4

2 回答 2

0

编辑:请注意,如果字段类型为 ,则以下情况为真TextType,但IntegerType适用于@Assert\Type("integer"). 这有点使我的答案无效/不相关......

您正在使用@Assert\Type("integer")注释,但这意味着:

  • value 必须是整数——作为 PHP 类型,就像调用is_int($value)
  • 并且由于数据来自表单(并且可能没有任何转换器,正如我在您的代码中看到的那样),它的类型是string
  • 因此,验证总是失败

你需要的是@Assert\Type("numeric")

  • 它相当于is_numeric($value)
  • 当它到达实体的字段时,它将被转换为字符串
于 2019-06-24T13:27:44.073 回答
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

答案是将实体中的 getter 和 setter 更改为:

    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。

于 2019-06-26T10:30:46.100 回答