2012-03-12 41 views

回答

48

這可以被Yii自身來完成,你不需要爲它的延伸。 然而,一個擴展可以幫助清理rules()方法如下所述:

http://www.yiiframework.com/extension/unique-attributes-validator/

這是代碼(從該網站複製),這將不使用擴展工作:

public function rules() { 
    return array(
     array('firstKey', 'unique', 'criteria'=>array(
      'condition'=>'`secondKey`=:secondKey', 
      'params'=>array(
       ':secondKey'=>$this->secondKey 
      ) 
     )), 
    ); 
} 

在如果$this->secondKey的值不在rules()內 - 方法可以在CActiveRecords中添加驗證器beforeValidate() - 方法如下:

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; 
} 
+0

我試過這種方法,但我沒有得到'$ this-> secondKey'的值$ – Khaleel 2013-07-08 08:50:11

+0

'$ this-> secondKey'應該是必須唯一的第二個屬性。您必須將其調整爲您的屬性名稱。 – cebe 2013-07-11 18:51:56

+0

我知道。我試着用我的屬性名稱。我不只是在'rules()' – Khaleel 2013-07-12 05:00:46

-5

可能是你可以在此rules添加到您的代碼

return array(
    array('name', 'unique', 'className'=>'MyModel', 'attributeName'=>'myName'), 
    array('version', 'unique', 'className'=>'MyModel', 'attributeName'=>'myVersion') 
); 
+3

這隻會驗證名稱是唯一的版本,單是獨一無二的。它不驗證一對'(name,version)'列。 – cebe 2012-03-13 21:35:13

7

您不需要rules()方法和第三方擴展的複雜內容。只需創建您自己的驗證方法。自己做就容易多了。

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"); 
    } 

} 
+0

+1簡單易用:) – AlphaMale 2014-04-06 15:52:50

4

他們已經在Yii1.14rc的下一個候選版本中添加了對唯一組合鍵的支持,但這裏有(另一個)解決方案。順便說一句,這段代碼在Yii框架將在下一個正式版本中使用的規則中使用相同的'attributeName'。

保護/模型/ Mymodel.php

public function rules() 
    { 
     return array(
      array('name', 'uniqueValidator','attributeName'=>array(
       'name', 'phone_number','email') 
     ), 
... 
  • 「名」在規則的開頭是你的窗體上的驗證錯誤將被連接到該屬性以後輸出。
  • 'attributeName'(數組)包含您想一起驗證爲組合鍵的一組鍵。

保護/組件/驗證/ 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.'); 
     } 
    } 

} 

只要你喜歡你可以使用盡可能多的屬性,這將您的所有CModels的工作。該檢查完成「存在」。

保護/配置/ main.php

'application.components.validators.*', 

您可能必須在上述行添加到您的配置的「進口」陣列中,使uniqueValidator.php將由Yii應用中找到。

積極的反饋和變化是非常受歡迎的!

+1

我仍然在1.13上,因爲我沒有時間升級一個漂亮的大應用程序。從快速測試來看,這很好,謝謝!它還避免了必須創建自定義驗證器(不難,授予但可以混亂),並通過傳遞動態值作爲第二個屬性(可以獲得_really_凌亂)來解決一些問題。 – ldg 2014-07-16 03:37:57

-2

這很容易。在你的數組中,包含一個在你的擴展類中創建的參數。

下一個代碼在Model中。

array('name', 'ext.ValidateNames', 'with'=>'lastname') 

接下來代碼是從ValidateNames類到擴展文件夾。

class ValidateNames extends CValidator 
{ 
    public $with=""; /*my parameter*/ 

    public function validateAttribute($object, $attribute) 
    { 
     $temp = $this->with; 
     $lastname = $object->$temp; 
     $name = $object->$attribute; 
     $this->addError($object,$attribute, $usuario." hola ".$lastname); 
    } 
} 
+1

您的回答不包含任何其他答案中至少沒有提供的信息。 – 2014-05-13 21:07:32

3

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

3

在Yii2:

public function rules() { 
    return [ 
     [['name'], 'unique', 'targetAttribute' => ['name', 'version']], 
    ]; 
} 
0

基於以上功能,這裏是一個功能,您可以添加到您的ActiveRecord模型

你會使用它像這樣,

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; 
}