Unique validation by update record

An ajax call with ‘enableAjaxValidation’ => true in form does not load the model in controller. The AR validation $model->getOldAttribute(‘username’) returns an empty result.

How do you do it best to avoid unique checking if the username is not changed?

One idea would be to load the model in the controller, but how do you pass the value to AR?

$un = $model->findOne (['username' => Yii::$app->request->post ('username')]);

Is there any better solution to solve the problem as the following?

Controller (update action):

    $this->user_model = User::findOne(Yii::$app->request->post()['User']['id']);

AR:

    ['username', 'unique',
       'when' => function ($model) {
       return $model->username != Yii::$app->controller->user_model->username;
    },],

Usually we don’t need to worry about the ‘update’ scenario when we use ‘unique’ validator. It is clever enough to prevent firing error when the value is not changed in ‘update’ scenario. I mean that your “when” trick is not necessary.

Hmm, maybe Yii doen’t know thats an update scenario. The update action gets the id and the model. How does Yii know if its an update szenario?

    public function actionUpdate($id)
   {
      $user_model = $this->findModel($id);
     ...

Or should I use a model and not an AR?

class User extends ActiveRecord implements IdentityInterface
{
...

Because unique validator only works for ActiveRecord, you have to use ActiveRecord.

The unique validator checks the model (AR) if it is a new record (ActiveRecord::isNewRecord) and changes the behavior according to it. If it’s a new one, the value should not exist in the current records. But if it’s not a new one, i.e., a one loaded from the db, the value can exist in the current records and the validator won’t add error to the model.

You should load it from the db, even if it is an ajax call. Otherwise the unique validator will assume that you are working with a new record.

Check modelExists methd of UniqueValidator.

Good to know. That’s curious, because I load the model in the validation action. So maybe its a problem with this AR or the storing. The saved model should show $_oldAttributes when loading, I’ll check this.