Pernahkan anda menjumpai error duplicate key value violates unique pada yii seperti gambar diatas? Pesan error diatas menjelaskan bahwa dalam database sudah terdapat data dengan yang anda inputkan sekarang. Dengan syarat pesan ini muncul ketika field database merupakan primary key atau unique sehingga ketika data ke-2 yang di inputkan sama maka akan tampil pesan error tersebut. Saya contohkan apabila dalam database terdapat data nomor 123A pada field no_pendaftaran kemudian anda menginputkannya lagi dengan nomor yang sama yaitu 123A maka akan tampil pesan error tersebut. Berikut ini akan saya paparkan 3 buah cara untuk mencegah terjadinya data ganda/ double :
1. Penggunaan try-catch
Contoh codenya seperti berikut:
Dalam lingkup try bernilai benar sedangkan dalam catch adalah value error yang akan di tampilkan.
Script ini hanya menampung error dalam sebuah tampilan gui message flash saja. Cara ini kurang cantik bila di gunakan untuk validasi sebuah kriteria. Cara yang ke-2 ini adalah rekomendasi dari Muhammad Rifki Mockie agar validasi lebih baik dan lebih cantik sesuai prosedur dari doc yii framework. Berikut ini tips ke-2:
2. Penggunaan validasi dari Rule di ModelStep-1
Buatlah file proctected/components/CompositeUniqueKeyValidator.php
Kemudian isikan script seperti berikut ini:
<?php
/**
* CompositeUniqueKeyValidator class file.
*/
class CompositeUniqueKeyValidator extends CValidator {
/**
* @var string comma separated columns that are unique key
*/
public $keyColumns;
public $errorMessage = '"{columns_labels}" are not unique';
/**
* @var boolean whether the error message should be added to all of the columns
*/
public $addErrorToAllColumns = false;
/**
* @param CModel $object the object being validated
* @param string $attribute if there is an validation error then error message
* will be added to this property
*/
protected function validateAttribute($object, $attribute) {
$class = get_class($object);
Yii::import($class);
$keyColumns = explode(',', $this->keyColumns);
if (count($keyColumns) == 1) {
throw new CException('CUniqueValidator should be used instead');
}
$columnsLabels = $object->attributeLabels();
$criteria = new CDbCriteria();
$keyColumnsLabels = array();
foreach ($keyColumns as &$column) {
$column = trim($column);
$criteria->compare($column, $object->$column);
$keyColumnsLabels[] = $columnsLabels[$column];
}
unset($column);
$criteria->limit = 1;
if ($class::model()->count($criteria)) {
$message = Yii::t('yii', $this->errorMessage, array(
'{columns_labels}' => join(', ', $keyColumnsLabels)
));
if ($this->addErrorToAllColumns) {
foreach ($keyColumns as $column) {
$this->addError($object, $column, $message);
}
}
else {
$this->addError($object, $attribute, $message);
}
}
}
}
?>
Step-2Tambahkan validasi pada method rule di model anda:
<?php
public function rules(){
return array(
array('no_karyawan', 'CompositeUniqueKeyValidator', 'keyColumns' => 'no_karyawan, id_tempat'));
} ?>
Maksud dari rule ini adalah memvalidasi field no_karyawan dan id_tempat yang keduanya merupakan primary key agar menjadi field unique key.
3. Pengecekan databaseStep 1 - Membuat coditional field apa yang ingin dicek, contohnya seperti kode program berikut:
$isExist = Mhs::model()->exists(
array('condition'=>'nim = :nim',
'params'=>array(
':nim'=>$_POST['NilaiKknPpl']['nim']
),
));
Kemudian buat kondisi untuk membaca kode program diatas. Yaitu seperti kode berikut ini:if($isExist){
//True atau ada dalam database
}else{
//False atau tidak ada dalam database
}
Untuk saya pribadi lebih menganjurkan anda untuk memakai cara ke-3 karena langsung melakukan pengecekan pada database, apakah data sudah ada atau tidak. Cara pertama yaitu try... catch tidak cocok untuk pengecekan redudance data. Berbeda dengan cara kedua yang masih error dalam proses updatenya karena validasinya masih membaca primary key sebagai data yang sudah ada dalam database sehingga proses updatenya gagal walaupun proses createnya sudah oke dalam masalah validasi.
maaf gan bisa minta contoh nya gak untuk yang model ke 3...
ReplyDeleteterima kasih
maaf mas, saya sudah coba buat untuk sample nomor 3
ReplyDeletetapi sepertinya saya masih bingung
':nim'=>$_POST['NilaiKknPpl']['nim']
'NilaiKknPpl' tersebut apa yah?
ini yang sudah saya kerjakan pada actionCreate
public function actionCreate()
{
$model = new Rokok;
$isExist = Rokok::model()->exists(
array('condition'=>'merk_rokok = :merk_rokok',
'params'=>array(
':merk_rokok'=>$_POST['disini parameternya apa yah?']['merk_rokok']
),
)
);
if($isExist){
if(isset($_POST['Rokok']))
{
$model->attributes = $_POST['Rokok'];
if($model->save())
$this->redirect(array(
'view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}else{
//False atau tidak ada dalam database
}
}
terimakasih mas sebelumnya,