2017-01-19 31 views
0

我對Symfony非常陌生,並且在實現RESTful API時遇到問題,特別是傳入JSON不包含所有參數的表單。Symfony 2.8表單強制缺少布爾值爲false

到目前爲止,我設置了一個處理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; 

也許選項= {」默認「= FALSE}在實體配置中負責這一點,但它雖然使得sen se在持久層中具有false作爲默認值,在負責將表單數據(或缺少數據)映射到對象的層中將其強制爲false並不是我所需要的。 任何幫助將不勝感激!對於實體

+0

在案例2中,你做你的實體的更新? –

+0

@MatkoĐipalo是的,在情況2中,如果字段不爲空,我更新實體。正如你所看到的那樣,這些字段總是非空的,即使它們沒有在請求中提供。 – SCO

回答

0

默認字段值設置如下:

protected $isTutorialSeen = null; 

,但我不知道是否會在這種情況下幫助。

+0

試過了,但沒有幫助。 – SCO

0

當您要創建一個全新的資源時,您使用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); 
+0

將動詞從POST更改爲PATCH是不可能的,所以我嘗試使用PUT。我用$ form-> submit($ request-> request-> all(),true)替換了ControllerUtils :: handleForm($ request,$ form)。行爲沒有改變。 $ form-> get('isPaired') - > getData()返回的值仍然是假的,就像它沒有被無效一樣。 – SCO

相關問題