【问题标题】:yii2 on update action for unique attributeyii2 关于唯一属性的更新操作
【发布时间】:2023-04-05 09:42:01
【问题描述】:

在用户模型中我有以下规则

[['username', 'email'], 'unique'],

我想要做的是,在新用户创建期间、更新时(当用户输入另一个用户名或电子邮件以检查它是否唯一时)使此规则可用。但是如果我不更改当前用户模型中的用户名(在更新操作中),即使用户没有编辑当前用户名和电子邮件并且只保存填写的表单(使用当前值),也会出现错误“用户名不是唯一的”。

例如,您的用户名是:user1。您打开了更新操作并仅更改了密码。在这种情况下,我的配置给 user1 is not unique message。另一种情况是,您将用户名更改为:user2 并且它可以正常工作

这是动作代码:

public function actionMe()
{
    $data["model"] = $model = $this->findModel(Yii::$app->user->id);

    if ($model->load(Yii::$app->request->post())) {
        if (trim($model->password) != "")
            $model->setPassword($model->password);
        if ($model->validate() && $model->save())
            return $this->redirect(['site/index']);
    }
    return $this->render('me', $data);
}

如何防止这种行为?

【问题讨论】:

  • 我试过你的情况,但没有得到相同的结果。另外我的 yii2 版本是2.0.11.2。你用的是哪个版本的 yii2?
  • 我觉得不是版本的问题,我们的版本是一样的
  • 这毫无意义。你能列出你模特的规则吗?
  • 那些规则就像字符串一样简单,没有任何场景

标签: validation yii2 unique


【解决方案1】:

您可以通过两种方式进行操作,第一种方式更多来自 Yii2 Starter Kit。在这里,您将这些添加到您的规则中。并将下面这个函数添加到您的用户窗体的末尾。

[ 'username', 'unique', 'targetClass' => User::className(), 'filter' => function ($query) {
                if (!$this->getModel()->isNewRecord) {
                    $query->andWhere(['not', ['id'=>$this->getModel()->id]]);
                }
            }],



 /**
     * @return app/models/User
     */
    public function getModel()
    {
        if (!$this->model) {
            $this->model = new User();
        }
        return $this->model;
    }

第二种方法是创建您自己的验证器并在更新场景中使用它。 例如:

[['username', 'email'], 'myUniqueValidator','on'=>'update'],

 public function myUniqueValidator($attribute,$params){
        if(!$this->hasErrors()){
            if(User::find()->where([$attribute=>$this->$attribute])->andWhere(['<>','id',Yii::$app->user->id])){

             }

        }
    }

那么你应该为你的动作添加一个场景。

public function actionMe()
{
    $data["model"] = $model = $this->findModel(Yii::$app->user->id);

    if ($model->load(Yii::$app->request->post())) {
         $model->setScenario('update');
        if (trim($model->password) != "")
            $model->setPassword($model->password);
        if ($model->validate() && $model->save())
            return $this->redirect(['site/index']);
    }
    return $this->render('me', $data);
}

【讨论】:

    【解决方案2】:

    我为更新用户数据创建单独的模型,更新模型中的规则如下:

            ['username', 'trim'],
            ['username', 'required'],
            [
              'username',
              'unique',
              'targetClass' => '\frontend\models\Customer',
              'message' => Yii::t('app', 'This username has already been taken.'),
              'when' => function ($model){
                  return $model->username != Yii::$app->user->identity->username;
              }
            ],
            ['username', 'string', 'min' => 2, 'max' => 255],
    
            ['email', 'trim'],
            ['email', 'required'],
            ['email', 'email'],
            ['email', 'string', 'max' => 255],
            [
              'email',
              'unique',
              'targetClass' => '\frontend\models\Customer',
              'message' => Yii::t('app','This email address has already been taken.'),
              'when' => function ($model){
                  return $model->email != Yii::$app->user->identity->email;
              }
            ],
    
            //['password', 'required', 'skipOnEmpty' => true],
            ['password', 'string', 'min' => 6],
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 2016-02-20
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多