Symfony 和 FOSRestBundle:表单未填充实体数据

Symfony and FOSRestBundle: form not filling entity data

我正在尝试使用 FOS Rest 包构建一个非常简单的 rest api。 GET 和 DELETE 方法很简单,但我正在努力 post。

这是我的一个非常简单的实体的 post 方法(只有 "name" 和 "active" 属性):

/**
     * @param Request $request
     * @return array|View
     */
    public function postSkillsAction(Request $request)
    {
        $skill = new Skill();

        $form = $this->createForm(SkillType::class, $skill);

        $form->submit($request->request->get($form->getName()));

        if ($form->isSubmitted() && $form->isValid()) {
            $this->entityManager->persist($skill);
            $this->entityManager->flush();
            return $this->redirectToRoute('skillset', ['id' => $skill->getId()], Response::HTTP_CREATED);
        }

        return [
            'form' => $form
        ];
    }

这是我的表格:

final class SkillType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) : void
    {
        $builder
            ->add(
                'name', TextType::class, [
                'label' => 'fields.name'
            ])
            ->add('active', CheckboxType::class, [
                'label' => 'fields.active',
                'required' => false
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class'      => Skill::class,
            'csrf_protection' => false
        ]);
    }

    /**
     * @return string
     */
    public function getName() : string
    {
        return 'skill';
    }

}

问题是,当我执行 /api/skills 通过 post 名称发送并激活时,我收到以下 SQL 错误

An exception occurred while executing 'INSERT INTO skill (name, active, created_at, updated_at) VALUES (?, ?, ?, ?)' with params [null, 0, "2017-03-19 19:49:37", "2017-03-19 19:49:37"]

表单数据正确到达,我已经调试,如果我执行 $request->request->get('name') 我得到了正确的值。

我找不到任何更新的示例,例如这个示例是针对 symfony 2 的,尽管我尽量遵循它 https://github.com/gimler/symfony-rest-edition/blob/2.7/src/AppBundle/Controller/NoteController.php

更新 如果我执行 var_dump of var_dump($request->request->all());我得到

array(
'name' => a,
'active' => 1
)

这是实体

final class Skill
{
    use OptionalDateTimeTrait;

    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var integer
     */
    private $active;

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * @param int $id
     * @return Skill
     */
    public function setId(int $id) : self
    {
        $this->id = $id;

        return $this;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     * @return self
     */
    public function setName(string $name) : self
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Set active
     *
     * @param boolean $active
     *
     * @return Skill
     */
    public function setActive($active) : self
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean
     */
    public function getActive()
    {
        return $this->active;
    }
}

正如您告诉我们的,当您调用 $request->request->get('name') 时,您会得到正确的值。请查看将数据传递给表单的代码:

$form->submit($request->request->get($form->getName()));

这行代码意味着您只传递给表单的那些数据,这些数据以数组的形式出现,以您的表单命名(在您的情况下为技能)。在这种情况下你应该通过 POST 这样的数据:

skill[name]=John
skill[active]=1

如果您不想使用数组包装器通过 POST 发送数据,您必须向您的表单提交整个请求:

$form->submit($request->request->all());

这两种方法在技术上都是正确的,但第二种方法实际上是反模式的。