J'ai un tableau comme celui-ci:.
Cela peut être fait par Yii lui-même, vous n'avez pas besoin d'une extension pour cela . Cependant, une extension peut aider à nettoyer la méthode rules()
comme décrit ici:
http://www.yiiframework.com/extension/unique-attributes-validator/
C'est le code (copié depuis ce site) qui fonctionnera sans utiliser l'extension:
public function rules() {
return array(
array('firstKey', 'unique', 'criteria'=>array(
'condition'=>'`secondKey`=:secondKey',
'params'=>array(
':secondKey'=>$this->secondKey
)
)),
);
}
Si la valeur de $this->secondKey
n'est pas disponible dans la méthode rules()
-, vous pouvez ajouter le validateur dans la méthode CActiveRecords beforeValidate()
- comme ceci:
public function beforeValidate()
{
if (parent::beforeValidate()) {
$validator = CValidator::createValidator('unique', $this, 'firstKey', array(
'criteria' => array(
'condition'=>'`secondKey`=:secondKey',
'params'=>array(
':secondKey'=>$this->secondKey
)
)
));
$this->getValidatorList()->insertAt(0, $validator);
return true;
}
return false;
}
Vous n'avez pas besoin du contenu compliqué de la méthode rules () ni des extensions tierces. Créez simplement votre propre méthode de validation. C'est beaucoup plus facile de le faire vous-même.
public function rules()
{
return array(
array('firstField', 'myTestUniqueMethod'),
);
}
public function myTestUniqueMethod($attribute,$params)
{
//... and here your own pure SQL or ActiveRecord test ..
// usage:
// $this->firstField;
// $this->secondField;
// SELECT * FROM myTable WHERE firstField = $this->firstField AND secondField = $this->secondField ...
// If result not empty ... error
if (!$isUnique)
{
$this->addError('firstField', "Text of error");
$this->addError('secondField', "Text of error");
}
}
Yii1:
http://www.yiiframework.com/extension/composite-unique-key-validatable/
Yii2:
// a1 needs to be unique
['a1', 'unique']
// a1 needs to be unique, but column a2 will be used to check the uniqueness of the a1 value
['a1', 'unique', 'targetAttribute' => 'a2']
// a1 and a2 need to be unique together, and they both will receive error message
[['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']]
// a1 and a2 need to be unique together, only a1 will receive error message
['a1', 'unique', 'targetAttribute' => ['a1', 'a2']]
// a1 needs to be unique by checking the uniqueness of both a2 and a3 (using a1 value)
['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']]
http://www.yiiframework.com/doc-2.0/yii-validators-uniquevalidator.html
Ils ont ajouté la prise en charge de clés composites uniques dans la prochaine version candidate de Yii1.14rc, mais voici (encore une autre) solution. En passant, ce code utilise le même 'attributName' dans les règles que le framework Yii utilisera dans la prochaine version officielle.
protected/models/Mymodel.php
public function rules()
{
return array(
array('name', 'uniqueValidator','attributeName'=>array(
'name', 'phone_number','email')
),
...
protected/components/validators/uniqueValidator.php
class uniqueValidator extends CValidator
{
public $attributeName;
public $quiet = false; //future bool for quiet validation error -->not complete
/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param CModel $object the object being validated
* @param string $attribute the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
// build criteria from attribute(s) using Yii CDbCriteria
$criteria=new CDbCriteria();
foreach ( $this->attributeName as $name )
$criteria->addSearchCondition( $name, $object->$name, false );
// use exists with $criteria to check if the supplied keys combined are unique
if ( $object->exists( $criteria ) ) {
$this->addError($object,$attribute, $object->label() .' ' .
$attribute .' "'. $object->$attribute . '" has already been taken.');
}
}
}
Vous pouvez utiliser autant d'attributs que vous le souhaitez et cela fonctionnera pour tous vos CModels. La vérification est faite avec "existe".
protected/config/main.php
'application.components.validators.*',
Vous devrez peut-être ajouter la ligne ci-dessus à votre configuration dans le tableau "import" afin que le fichier uniqueValidator.php soit trouvé par l'application Yii.
Les retours positifs et les changements sont les bienvenus!
En Yii2:
public function rules() {
return [
[['name'], 'unique', 'targetAttribute' => ['name', 'version']],
];
}
En fonction de la fonction ci-dessus, voici une fonction que vous pouvez ajouter à votre modèle ActiveRecord.
Vous l'utiliseriez comme ça,
array( array('productname,productversion'), 'ValidateUniqueColumns', 'Product already contains that version'),
/*
* Validates the uniqueness of the attributes, multiple attributes
*/
public function ValidateUniqueColumns($attributes, $params)
{
$columns = explode(",", $attributes);
//Create the SQL Statement
$select_criteria = "";
$column_count = count($columns);
$lastcolumn = "";
for($index=0; $index<$column_count; $index++)
{
$lastcolumn = $columns[$index];
$value = Yii::app()->db->quoteValue( $this->getAttribute($columns[$index]) );
$column_equals = "`".$columns[$index]."` = ".$value."";
$select_criteria = $select_criteria.$column_equals;
$select_criteria = $select_criteria." ";
if($index + 1 < $column_count)
{
$select_criteria = $select_criteria." AND ";
}
}
$select_criteria = $select_criteria." AND `".$this->getTableSchema()->primaryKey."` <> ".Yii::app()->db->quoteValue($this->getAttribute( $this->getTableSchema()->primaryKey ))."";
$SQL = " SELECT COUNT(`".$this->getTableSchema()->primaryKey."`) AS COUNT_ FROM `".$this->tableName()."` WHERE ".$select_criteria;
$list = Yii::app()->db->createCommand($SQL)->queryAll();
$total = intval( $list[0]["COUNT_"] );
if($total > 0)
{
$this->addError($lastcolumn, $params[0]);
return false;
}
return true;
}