Tratando mensagem de Exceção [Integrity constraint violation: 1451 Cannot delete ...]

Boa tarde.

Meu sistema possui uma classe que não podem ser excluidos registros que estejam relacionados com outra tabela no sistema. Só podem ser excluidos registros que não possuam relacionamento.

Até ai tudo bem, a framework trata isso e não deixa que a exclusão aconteça, porém é lançado uma Exception com o erro 1451 para o usuário.

Gostaria de tratar essa Exceção e mostrar uma mensagem mais amigável ao usuario (Um Alert por exemplo).

Sugestões ???

Raphael,

na wiki tem uma explicação de como fazer isso: http://www.yiiframework.com/wiki/205/how-to-show-ajax-delete-status-in-cgridview-like-flash-messages/

qualquer dúvida é só postar.

Pessoal, desculpe resgatar um topico antigo.

É que eu tentei fazer o procedimento explicado nessa wiki (www.yiiframework.com/wiki/205/how-to-show-ajax-delete-status-in-cgridview-like-flash-messages/) mas não surtiu efeito algum. To usando a ultima versão do framework e gostaria de saber se alguem ja conseguiu fazer ou tem alguma sugestão.

Gustavo, posta seu código ae.

Opa, desculpe a demora. Segue abaixo meu codigo Newerton (sem o flash messages)

A view admin.php


<?php

$this->pageTitle = CHtml::encode(Yii::app()->name)." - Visitas Cadastradas";


Yii::app()->clientScript->registerScript('search', "

$('.search-button').click(function(){

    $('.search-form').toggle();

    return false;

});

$('.search-form form').submit(function(){

    $.fn.yiiGridView.update('visitas-grid', {

        data: $(this).serialize()

    });

    return false;

});

");

?>

<div class="flash-notice">Nova interface do Sistema de Controle de Visitas! Mais rápida e com melhores opções de filtro! <?php echo CHtml::link('<strong>Clique aqui se quiser usar a versão antiga</strong>','http://172.19.37.150/controle_visitas_antigo'); ?></div>

<!-- <h1>Visitas</h1> -->

<div id="sub">

<?php echo CHtml::link('Pesquisa avançada','#',array('class'=>'search-button')); ?>

<div class="search-form" style="display:none">

<p>

Para melhorar a pesquisa, você pode digitar parte do texto a ser pesquisdo, ou utilizar os operadores (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>

ou <b>=</b>) no início de cada valor no campo.<p> Ex.: Exibir todos registros exceto agencia 06, seria: <>6 no campo "agencia"  

</p>

<?php $this->renderPartial('_search',array(

    'model'=>$model,

)); ?>

</div>


</div><!-- search-form -->


<?php $this->widget('zii.widgets.grid.CGridView', array(

    'id'=>'visitas-grid',

    'dataProvider'=>$model->search(),

    'filter'=>$model,

    'enableSorting'=>true,

    'cssFile'=>'css/my_grid.css',

    'pager'=>array(

        'header'=>'Paginas',

        'cssFile'=>'css/my_pager.css',

    ),

     'afterAjaxUpdate' => 'reinstallDatePicker', // (#1)

    'columns'=>array(

        //'id_controle_visita',

        array(

            'name'=>'id_controle_visita',

            'type'=>'raw',

            'htmlOptions'=>array('width'=>'5%','style'=>'text-align:left'),

        ),


        array(

            'name'=>'id_gerente',

            'value'=>'$data->idGerente->nome_gerente',

            'type'=>'text',

            'header'=>'Gerente',

            'filter'=>CHtml::listData(Gerente::model()->findAll(), 'id_gerente', 'nome_gerente'),

        ),

        array(

            'name'=>'id_agencia',

            'value'=>'$data->idAgencia->sigla_agencia',

            'type'=>'text',

            'header'=>'Agencia',

            'filter'=>CHtml::listData(Agencia::model()->findAll(), 'id_agencia', 'sigla_agencia'),

        ),

        array(

            'name' => 'data_hora',

            'value' => 'date("d/m/Y", strtotime($data->data_hora))',

            'filter' => $this->widget('zii.widgets.jui.CJuiDatePicker', array(

                'model'=>$model, 

                'attribute'=>'data_hora', 

                'language' => 'pt-BR',

                'i18nScriptFile' => 'jquery.ui.datepicker-ja.js', // (#2)

                'htmlOptions' => array(

                    'id' => 'datepicker_for_due_date',

                    'size' => '10',

                ),

                'defaultOptions' => array(  // (#3)

                    'showOn' => 'focus', 

                    'dateFormat' => 'yy-mm-dd',

                    'altFormat' => 'dd/mm/yy',

                    'showOtherMonths' => true,

                    'selectOtherMonths' => true,

                    'changeMonth' => true,

                    'changeYear' => true,

                    'showButtonPanel' => true,

                )

            ), 

            true),

            ), 

        array(

            'name'=>'emp_pessoa',

            'header'=>'Emp / Pessoa',

            ),

        array(

            'name'=>'id_finalidade',

            'value'=>'$data->idFinalidade->desc_finalidade',

            'type'=>'text',

            'header'=>'Finalidade',

            'filter'=>CHtml::listData(Finalidades::model()->findAll(), 'id_finalidade', 'desc_finalidade'),

        ), 

        array(

            'name'=>'id_status',

            'value'=>'$data->idStatus->desc_status',

            'type'=>'text',

            'header'=>'Status',

            'filter'=>CHtml::listData(Status::model()->findAll(), 'id_status', 'desc_status'),


        ), 

        array(

            'name'=>'id_tipo_pessoa',

            'value'=>'$data->idTipoPessoa->desc_tipo_pessoa',

            'type'=>'text',

            'header'=>'Tipo',

            'filter'=>CHtml::listData(TipoPessoa::model()->findAll(), 'id_tipo_pessoa', 'desc_tipo_pessoa'),

        ), 

        array(

            'class'=>'CButtonColumn',

            'template'=>'{view} {update}',

            'buttons'=>array

                (

                    'view' => array

                    (

                    'label'=>'Visualizar detalhes da visita',

                    'imageUrl'=>Yii::app()->request->baseUrl.'/images/view.png',

                     ),

                    'update' => array

                    (

                    'label'=>'Alterar dados da visita',

                    'imageUrl'=>Yii::app()->request->baseUrl.'/images/edit.png',

                    ),

                ),

            ),

    ),

)); 

Yii::app()->clientScript->registerScript('re-install-date-picker', "

function reinstallDatePicker(id, data) {

    $('#datepicker_for_due_date').datepicker();

}

");

?>



E o controller:


<?php


class VisitasController extends Controller

{

	/**

	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

	 * using two-column layout. See 'protected/views/layouts/column2.php'.

	 */

	//public $layout='//layouts/column2';


	/**

	 * @return array action filters

	 */

	public function filters()

	{

		return array(

			'accessControl', // perform access control for CRUD operations

			'postOnly + delete', // we only allow deletion via POST request

		);

	}


	/**

	 * Specifies the access control rules.

	 * This method is used by the 'accessControl' filter.

	 * @return array access control rules

	 */

	public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','view'),

				'users'=>array('*'),

			),

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('create','update'),

				'users'=>array('*'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('admin','delete'),

				'users'=>array('*'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}


	/**

	 * Displays a particular model.

	 * @param integer $id the ID of the model to be displayed

	 */

	public function actionView($id)

	{

		$this->render('view',array(

			'model'=>$this->loadModel($id),

		));

	}


	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 */

	public function actionCreate()

	{

		$model=new Visitas;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Visitas']))

		{

			$model->attributes=$_POST['Visitas'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_controle_visita));

		}


		$this->render('create',array(

			'model'=>$model,

		));

	}


	/**

	 * Updates a particular model.

	 * If update is successful, the browser will be redirected to the 'view' page.

	 * @param integer $id the ID of the model to be updated

	 */

	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Visitas']))

		{

			$model->attributes=$_POST['Visitas'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_controle_visita));

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}


	/**

	 * Deletes a particular model.

	 * If deletion is successful, the browser will be redirected to the 'admin' page.

	 * @param integer $id the ID of the model to be deleted

	 */

	public function actionDelete($id)

	{

		$this->loadModel($id)->delete();


		// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

		if(!isset($_GET['ajax']))

			$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Visitas');

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}


	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new Visitas('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['Visitas']))

			$model->attributes=$_GET['Visitas'];


		$this->render('admin',array(

			'model'=>$model,

		));

	}


	/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 * @param integer the ID of the model to be loaded

	 */

	public function loadModel($id)

	{

		$model=Visitas::model()->findByPk($id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	/**

	 * Performs the AJAX validation.

	 * @param CModel the model to be validated

	 */

	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='visitas-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}



Pensei que ja tinha formatado o código já com o wiki de exemplo.

Mais o que deu de errado que não conseguiu executar o wiki?

Opa,

Fiz o procedimento mas ao tentar excluir um registro por exemplo, aparece a mesma mensagem (Integrity contraint…), aí pra postar aqui pensei q era pra postar a forma que estava…rs

Testando novamente agora, fiquei com duvida no controller. Onde exatamente eu coloco a parte do codigo:


try{

    $this->loadModel($id)->delete();

    if(!isset($_GET['ajax']))

        Yii::app()->user->setFlash('success','Normal - Deleted Successfully');

    else

        echo "<div class='flash-success'>Ajax - Deleted Successfully</div>";

}catch(CDbException $e){

    if(!isset($_GET['ajax']))

        Yii::app()->user->setFlash('error','Normal - error message');

    else

        echo "<div class='flash-error'>Ajax - error message</div>"; //for ajax}

No seu controller


public function actionDelete($id)

{

	try{

		$this->loadModel($id)->delete();

		if(!isset($_GET['ajax']))

			Yii::app()->user->setFlash('success','Normal - Deleted Successfully');

		else

			echo "<div class='flash-success'>Ajax - Deleted Successfully</div>";

	}catch(CDbException $e){

		if(!isset($_GET['ajax']))

			Yii::app()->user->setFlash('error','Normal - error message');

		else

			echo "<div class='flash-error'>Ajax - error message</div>"; //for ajax}

}

Na view/index.php antes da CGridView você coloca:




<div id="statusMsg">

<?php if(Yii::app()->user->hasFlash('success')):?>

    <div class="flash-success">

        <?php echo Yii::app()->user->getFlash('success'); ?>

    </div>

<?php endif; ?>

 

<?php if(Yii::app()->user->hasFlash('error')):?>

    <div class="flash-error">

        <?php echo Yii::app()->user->getFlash('error'); ?>

    </div>

<?php endif; ?>

</div>



E na CGridView na coluna dos botões, onde está usando a ‘class’=>‘CButtonColumn’, você acrescenta abaixo:


'afterDelete'=>'function(link,success,data){ if(success) $("#statusMsg").html(data); 

Altera o:


'template'=>'{view} {update}',

para:


'template'=>'{view} {update} {delete}',

Aparece esse erro: http://imageshack.us/photo/my-images/201/errogrid.jpg

Coloquei dessa forma a view


<?php


Yii::app()->clientScript->registerScript('search', "

$('.search-button').click(function(){

	$('.search-form').toggle();

	return false;

});

$('.search-form form').submit(function(){

	$.fn.yiiGridView.update('gerente-grid', {

		data: $(this).serialize()

	});

	return false;

});

");

?>


<h2>Administrar Gerentes</h2>

<div id="statusMsg">

<?php if(Yii::app()->user->hasFlash('success')):?>

    <div class="flash-success">

        <?php echo Yii::app()->user->getFlash('success'); ?>

    </div>

<?php endif; ?>

 

<?php if(Yii::app()->user->hasFlash('error')):?>

    <div class="flash-error">

        <?php echo Yii::app()->user->getFlash('error'); ?>

    </div>

<?php endif; ?>

</div>

<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'gerente-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'cssFile'=>'css/my_grid.css',

	'pager'=>array(

        'header'=>'Paginas',

        'cssFile'=>'css/my_pager.css',

    ),

	'columns'=>array(

		array(

            'name'=>'id_gerente',

            'type'=>'raw',

            'htmlOptions'=>array('width'=>'5%','style'=>'text-align:left'),

        ),

		array(

            'name'=>'login_gerente',

            'type'=>'raw',

            'htmlOptions'=>array('width'=>'20%','style'=>'text-align:left'),

        ),

		array(

            'name'=>'nome_gerente',

            'type'=>'raw',

            'htmlOptions'=>array('width'=>'30%','style'=>'text-align:left'),

        ),

        array(

            'name'=>'email_gerente',

            'type'=>'html',

            'header'=>'e-Mail',

            'htmlOptions'=>array('width'=>'30%','style'=>'text-align:center'),

        ),

		array(

            'name'=>'ativo_gerente',

            'type'=>'raw',

            'htmlOptions'=>array('width'=>'5%','style'=>'text-align:left'),

        ),

		array(

			'class'=>'CButtonColumn',

            'template'=>'{view} {update} {delete}',

            'afterDelete'=>'function(link,success,data){ if(success) $("#statusMsg").html(data); }',

		),

	),

)); ?>

E o controler:


<?php


class GerenteController extends Controller

{

	/**

	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

	 * using two-column layout. See 'protected/views/layouts/column2.php'.

	 */

	//public $layout='//layouts/column2';


	/**

	 * @return array action filters

	 */

	public function filters()

	{

		return array(

			'accessControl', // perform access control for CRUD operations

			'postOnly + delete', // we only allow deletion via POST request

		);

	}


	/**

	 * Specifies the access control rules.

	 * This method is used by the 'accessControl' filter.

	 * @return array access control rules

	 */

	public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','view'),

				'users'=>array('*'),

			),

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('create','update'),

				'users'=>array('@'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('admin','delete'),

				'users'=>array('admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}


	/**

	 * Displays a particular model.

	 * @param integer $id the ID of the model to be displayed

	 */

	public function actionView($id)

	{

		$this->render('view',array(

			'model'=>$this->loadModel($id),

		));

	}


	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 */

	public function actionCreate()

	{

		$model=new Gerente;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Gerente']))

		{

			$model->attributes=$_POST['Gerente'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_gerente));

		}


		$this->render('create',array(

			'model'=>$model,

		));

	}


	/**

	 * Updates a particular model.

	 * If update is successful, the browser will be redirected to the 'view' page.

	 * @param integer $id the ID of the model to be updated

	 */

	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Gerente']))

		{

			$model->attributes=$_POST['Gerente'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_gerente));

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}


	/**

	 * Deletes a particular model.

	 * If deletion is successful, the browser will be redirected to the 'admin' page.

	 * @param integer $id the ID of the model to be deleted

	 */

	public function actionDelete($id)

	{

		try{

                $this->loadModel($id)->delete();

                if(!isset($_GET['ajax']))

                        Yii::app()->user->setFlash('success','Normal - Deleted Successfully');

                else

                        echo "<div class='flash-success'>Ajax - Deleted Successfully</div>";

        }catch(CDbException $e){

                if(!isset($_GET['ajax']))

                        Yii::app()->user->setFlash('error','Normal - error message');

                else

                        echo "<div class='flash-error'>Ajax - error message</div>"; //for ajax

            }

		$this->loadModel($id)->delete();


		// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

		if(!isset($_GET['ajax']))

			$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Gerente');

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}


	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new Gerente('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['Gerente']))

			$model->attributes=$_GET['Gerente'];


		$this->render('admin',array(

			'model'=>$model,

		));

	}


	/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 * @param integer the ID of the model to be loaded

	 */

	public function loadModel($id)

	{

		$model=Gerente::model()->findByPk($id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	/**

	 * Performs the AJAX validation.

	 * @param CModel the model to be validated

	 */

	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='gerente-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}



Obs.: Se eu coloco ‘ajaxUpdate’=>false, o sistema mostra o erro, aí clico em voltar, aí sim a mensagem de erro tratada aparece…

Essa:




Yii::app()->user->setFlash('error','Erro ao excluir esse registro!');

Tem dois $this->loadModel($id)->delete();

Deixa somente o que está dentro do try{…}.

assim:




public function actionDelete($id)

        {

                try{

                    $this->loadModel($id)->delete();

                    if(!isset($_GET['ajax']))

                        Yii::app()->user->setFlash('success','Normal - Deleted Successfully');

                    else

                        echo "<div class='flash-success'>Ajax - Deleted Successfully</div>";

                } catch(CDbException $e){

                    if(!isset($_GET['ajax']))

                        Yii::app()->user->setFlash('error','Normal - error message');

                    else

                        echo "<div class='flash-error'>Ajax - error message</div>"; //for ajax

                }


                // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

                if(!isset($_GET['ajax']))

                        $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

        }

Era isso mesmo Newerton! Funcionou corretamente

Valeu cara ;)