Symfony 2.8表示强制缺少布尔值为false

时间:2017-01-19 10:09:02

标签: json forms symfony fosrestbundle

我对Symfony很新,并且在实现RESTful API时遇到问题,特别是传入的JSON不包含所有参数的表单。

到目前为止,我设置了一个处理POST请求的控制器。该应用程序POST一个包含isPaired和/或isTutorialSeen字段的JSON。

  • 案例1(工作案例):

当POST查询包含{"isTutorialSeen":true, "isPaired": true}时,当我尝试$form->get('isPaired')->getData()$form->get('isTutorialSeen')->getData()时,这两个字段都设置为true。这就是我的期望。

  • 案例2(非工作案例):

当POST查询包含{"isTutorialSeen":true}时,我可以看到当我尝试$form->get('isPaired')->getData()时,表单的isPaired字段设置为false。可能是因为该字段未在JSON中传递。不在JSON中传递它应该具有含义"不要更新它",而不是"将其设置为false"。与HTTP' PATCH'相同语法。

我抓挠我的头发,想弄清楚我怎么能得到一个“无效”的头发。例如,而不是“假”'回到这里。

我的控制器实现如下:

/**
     * @Rest\Post("/installation/state")
     *
*/
public function installationStateAction(Request $request, Subscription $subscription)
{
    $view = null;

    $form = $this->createForm(InstallationStateType::class);
    ControllerUtils::handleForm($request, $form);

    if ($form->isValid()) {
        $isPaired    = $form->get('isPaired')->getData();
        $isTutorialSeen = $form->get('isTutorialSeen')->getData();

        if ($isPaired !== null)
            $subscription->setIsPaired($isPaired);

        if ($isTutorialSeen !== null)
            $subscription->setIsTutorialSeen($isTutorialSeen);

        $this->getDoctrine()->getManager()->flush($subscription);
    }

     $view = $this->view($subscription, Codes::HTTP_OK);
     return $this->handleView($view);
}

InstallationStateType如下:

/**
 * Form for InstallationState.
 */
class InstallationStateType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('isTutorialSeen', CheckboxType::class, ['required' => false]);
        $builder->add('isPaired', CheckboxType::class, ['required' => false]);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $defaultsOptions = [
            'data_class' => null
        ];

        $resolver->setDefaults($defaultsOptions);
    }

    public function getName()
    {
        return 'installationstate';
    }
}

订阅实体字段为:

/**
 * @ORM\Column(type="boolean", name="is_paired", options={"default"=FALSE})
 *
 * @JSON\Expose
 * @JSON\Groups({"api_process"})
 * @JSON\Since("1.0")
 * @JSON\SerializedName("isPaired")
 *
 * @var boolean
 */
protected $isPaired;

/**
 * @ORM\Column(type="boolean", name="is_tutorial_seen", options={"default"=FALSE})
 *
 * @JSON\Expose
 * @JSON\Groups({"api_process"})
 * @JSON\Since("1.0")
 * @JSON\SerializedName("isTutorialSeen")
 *
 * @var boolean
 */
protected $isTutorialSeen;

实体配置中的options = {" default" = FALSE}可能是对此负责的,但是在持久层中将false作为默认值是有意义的,将其强制为false在负责将表单数据(或缺少数据)映射到对象的层中,这不是我需要的。 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:-1)

实体的默认字段值设置如下:

protected $isTutorialSeen = null;

但我不确定在这种情况下是否会有所帮助。

答案 1 :(得分:-1)

当您要创建一个全新的资源时,您使用POST方法。根据设计,POST请求方法请求Web服务器接受并存储请求消息正文中包含的数据。

如果您决定更新资源,则应创建PUT或PATCH请求。 PATCH主要就像PUT一样,除非您不需要发送整个资源主体。

因此,您必须更改的第一件事是 - 使用PUT(或PATCH)进行更新。

如果您要使用PUT,则必须发送资源的完整表示。如果您没有发送isPaired,服务器应该使其无效 - 在您的情况下,服务器会将其设置为默认值。

如果要使用PATCH,可以省略isPaierd,但不能更改,但必须找到提交表单的代码,并添加值为true的第二个参数。

$form->submit($data, true);

的Symfony \元器件\表格| FormInterface:

/**
 * Submits data to the form, transforms and validates it.
 *
 * @param null|string|array $submittedData The submitted data
 * @param bool              $clearMissing  Whether to set fields to NULL
 *                                         when they are missing in the
 *                                         submitted data.
 *
 * @return FormInterface The form instance
 *
 * @throws Exception\AlreadySubmittedException If the form has already been submitted.
 */
public function submit($submittedData, $clearMissing = true);