首页 文章

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

提问于
浏览
0

我是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中传递它应该具有"don't update it"的含义,而不是"set it to false" . 与HTTP 'PATCH'语法相同 .

我正在抓挠我的头发试图弄清楚我怎么能得到一个'null',而不是一个'假'回来 .

我的控制器实现如下:

/**
     * @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 回答

  • -1

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

    protected $isTutorialSeen = null;
    

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

  • -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);
    

相关问题