开发者

sfValidatorDoctrineUnique in an update/edit context

I'm using a form class in two separate contexts: both to create a new record and also to edit that record. I've set up a post-validator as follows to check that the URL field is unique.

$this->validatorSchema->setPostValidator(new sfValidatorAnd(array(
   new sfValidatorDoctrineUnique(array('model' => 'Page', 'colu开发者_Python百科mn' => array('url')), array('invalid' => 'This URL already exists.'))
)));

The validator works great when I'm creating a new record. However, when editing an existing record, it throws an error because it detects itself as a duplicate. In other words, if I edit the record but make no changes to the URL, it throws a duplicate error.

This must be a common issue so I'm wondering what the Symfony way of dealing with this would be? Basically I'd like it to ignore itself when saving (no duplicate exists) but still run the post-validator to ensure no true duplicates exist.


The update situation is indeed handled by sfValidatorDoctrineUnique.

In your case if object with given URL already exists validator will check if you're performing an update operation. Check is made with sfValidatorDoctrineUnique::isUpdate() method.

Your primary key(s) need to be in the submitted values.

By default primary key is introspected. You can provide it with *primary_key* option passed to the validator.


As noted in other answers, it is important to make sure of the following:

  • The PK value for the updated object must be present in the submitted form values.
  • The sfValidatorDoctrineUnique validator must be aware of all values submitted with the form.

In order to accomplish this, you must perform the following steps:

  1. Add a hidden input that contains (usually) the PK value for your object:

    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
          ));
        }
    
        ...
      }
    
      ...
    }
    
    • Note that this extra input only needs to be added if you are updating.
       
  2. Move the sfValidatorDoctrineUnique to the post-validation phase:

    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'
        )));
      }
    
      ...
    }
    
    • You will need to use $this->mergePostValidator() to add the validator to the post-validation phase so that all submitted values are provided to the validator.

    • Note that you still need to supply a validator for the unique column widget, or else you will get an "Unexpected extra form field" error when you submit the form.

  3. Ensure that you are passing the object being updated to the constructor of your form:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜