2011-02-24 31 views
6

我在兩個單獨的上下文中使用表單類:既創建一個新記錄,也編輯該記錄。我已經設置了後驗證器,如下所示,以檢查URL字段是否唯一。更新/編輯上下文中的sfValidatorDoctrineUnique

$this->validatorSchema->setPostValidator(new sfValidatorAnd(array(
    new sfValidatorDoctrineUnique(array('model' => 'Page', 'column' => array('url')), array('invalid' => 'This URL already exists.')) 
))); 

當我創建一條新記錄時,驗證器很有效。但是,在編輯現有記錄時,由於它將自己檢測爲重複,所以會引發錯誤。換句話說,如果我編輯記錄但不更改URL,則會引發重複錯誤。

這一定是一個普遍的問題,所以我想知道Symfony的處理方式是什麼?基本上我希望它在保存時忽略自身(不存在重複),但仍然運行後驗證器以確保不存在真正的重複。

+0

湯姆,請讓我知道你找到了解決辦法,因爲我有相同問題。謝謝。 – tipu 2011-04-18 20:59:43

+1

我的解決方案發現:sfValidatorDoctrineUnique的第一個參數應該有一個鍵「primary_key」,值應​​該是表的主鍵。那麼您需要確保您的表單中的名稱與主鍵匹配。所以如果你正在編輯一個模型頁面,其ID爲3,你需要。最後我還將primary_key列放在我的表單中,所以$ this-> setValidator('id',new sfValidatorString(array('required'=> true)))。總而言之,3個文件的變化完成了工作。 – tipu 2011-04-18 21:56:17

回答

6

更新情況確實由sfValidatorDoctrineUnique處理。

在你的情況下,如果具有給定URL的對象已經存在,驗證器將檢查你是否正在執行更新操作。檢查是用sfValidatorDoctrineUnique :: isUpdate()方法。

您的主鍵需要在提交的值中。

默認情況下,主鍵是內省的。你可以爲它提供* primary_key *選項傳遞給驗證器。

+0

謝謝,聽起來像我正在尋找。你能提供一個如何使用它的簡單例子嗎?似乎沒有很好的記錄。 – Tom 2011-02-24 22:31:51

+0

....不用擔心,想通了。最初想到我需要調用這種方法。謝謝你的幫助。 – Tom 2011-02-24 23:17:30

+1

hi kuba, 你能解釋一下如何使用sfValidatorDoctrineUnique :: isUpdate()或sfValidatorDoctrineUnique與primary_key選項的例子 – 2011-07-12 12:50:18

4

在其他的答案指出,一定要確保以下是很重要的:

  • 的更新對象的PK值,必須在提交表單值。
  • sfValidatorDoctrineUnique驗證程序必須知道全部與表單一起提交的值。

爲了做到這一點,你必須執行以下步驟:

  1. 添加包含(通常)爲對象的PK值的隱藏輸入:

    class MyModelForm extends BaseMyModelForm 
    { 
        public function configure() 
        { 
        if(! $this->isNew()) 
        { 
         $this->widgetSchema['id'] = new sfWidgetFormInputHidden(); 
         $this->validatorSchema['id'] = new sfValidatorNumber(array(
          'required' => true 
         , 'min'  => 1 
        )); 
        } 
    
        ... 
        } 
    
        ... 
    } 
    
    • 請注意,如果您正在更新,只需要添加此額外輸入。
       
  2. 移動的sfValidatorDoctrineUnique到後確認階段:

    class MyModelForm extends BaseMyModelForm 
    { 
        public function configure() 
        { 
        $this->widgetSchema['unique_column'] = new sfWidgetFormInputText(); 
        $this->validatorSchema['unique_column'] = new sfValidatorPass(); 
    
        ... 
    
        $this->mergePostValidator(new sfValidatorDoctrineUnique(array(
         'required' => true 
         , 'model' => 'MyModel' 
         , 'column' => 'unique_column' 
        ))); 
        } 
    
        ... 
    } 
    
    • 您將需要使用$this->mergePostValidator()來驗證添加到驗證後階段,使所有提交的值被提供給驗證器。

    • 請注意,您仍然需要爲唯一列小部件提供驗證程序,否則當您提交表單時,您會收到「意外的額外表單字段」錯誤。

  3. 確保您傳遞對象被更新到窗體的構造函數:

    $this->form = new MyModelForm($this->getRoute()->getObject());