7

新しいレコードを作成するためと、そのレコードを編集するための 2 つの別々のコンテキストでフォーム クラスを使用しています。URLフィールドが一意であることを確認するために、次のようにポストバリデーターを設定しました。

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

バリデーターは、新しいレコードを作成するときにうまく機能します。ただし、既存のレコードを編集すると、それ自体が重複として検出されるため、エラーがスローされます。つまり、レコードを編集しても URL を変更しないと、重複エラーがスローされます。

これは一般的な問題に違いないので、Symfony でこれを処理するにはどうすればよいのでしょうか? 基本的に、保存時にそれ自体を無視して (重複は存在しません)、ポストバリデーターを実行して、真の重複が存在しないようにしたいと考えています。

4

2 に答える 2

6

更新状況は実際に sfValidatorDoctrineUnique によって処理されます。

あなたの場合、指定された URL を持つオブジェクトが既に存在する場合、バリデーターは更新操作を実行しているかどうかを確認します。チェックはsfValidatorDoctrineUnique::isUpdate()メソッドで行います。

主キーは、送信された値に含まれている必要があります。

デフォルトでは、主キーはイントロスペクトされます。バリデーターに渡される *primary_key* オプションで提供できます。

于 2011-02-24T22:10:38.650 に答える
5

他の回答で述べたように、次のことを確認することが重要です。

  • 更新されたオブジェクトの 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());
    
于 2011-12-30T17:13:52.613 に答える