yii2 关于唯一属性的更新操作
yii2 on update action for unique attribute
在用户模型中我有以下规则
[['username', 'email'], 'unique'],
我想做的是,在新用户创建和更新时(当用户输入另一个用户名或电子邮件以检查它是否唯一时)使此规则可用。但是,如果我不更改当前用户模型中的用户名(在更新操作中),即使用户不编辑当前用户名和电子邮件而只是保存填写的表单(使用当前值),也会出现错误 "username is not unique" .
例如,您的用户名是:user1。您打开了更新操作并仅更改了密码。在这种情况下,我的配置给 user1 is not unique 消息。另一种情况是,您将用户名更改为: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 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);
}
我为更新用户数据创建了单独的模型,更新模型中的规则如下:
['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],
在用户模型中我有以下规则
[['username', 'email'], 'unique'],
我想做的是,在新用户创建和更新时(当用户输入另一个用户名或电子邮件以检查它是否唯一时)使此规则可用。但是,如果我不更改当前用户模型中的用户名(在更新操作中),即使用户不编辑当前用户名和电子邮件而只是保存填写的表单(使用当前值),也会出现错误 "username is not unique" .
例如,您的用户名是:user1。您打开了更新操作并仅更改了密码。在这种情况下,我的配置给 user1 is not unique 消息。另一种情况是,您将用户名更改为: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 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);
}
我为更新用户数据创建了单独的模型,更新模型中的规则如下:
['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],