getErrors to string

Hi!

I want throw an exception on error when saving an active record. Here is an example of my getErrors:


Array ( [f_port] => Array ( [0] => Port must be an integer. ) )

So here is my code:


if($network->save())

	$transaction->commit();

else

{

	foreach ($network->getErrors () as $attribute => $error)

	{

		foreach ($error as $message)

		{

			throw new Exception($attribute.": ".$message);

		}

	}

}

Is there a better way than two foreach for generating my exception?

Thanks!

Is there are reason why you are doing this? You can’t throw multiple exceptions like that in one go. Also, I don’t think you should be throwing exceptions in the first place for validation errors.

Hi,

I think you can try this:


Yii::app()->user->setFlash('error',  CHtml::errorSummary($network));

Hi,

In fact my data come from a form without validation. So, in my controller, if an error appears during saving the object, I want give a reason to my user (In my example, the port number entered in my form is not an integer).

My controller is called with Ajax and return result with a json object.

Hello,

I am not sure whether you have validation rules in your AR model or not.

This post should show you the way:

http://www.yiiframework.com/forum/index.php/topic/23236-extension-how-to-display-validation-errors-comming-from-ajax-validation/

Thanks.

Indeed CActiveForm::validate() return what I want.

However, my form send me several object to insert in my database. So here is my controller:


public function actionSaveSiteInformation()

{

		$result=array();

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

		{

			foreach ($_POST['network'] as $key=>$network_form) 

			{

				$network=new t_network;

				$network->attributes=$network_form;

				$errors=CActiveForm::validate($network);

				if($errors !== '[]') 

					$result['network'][$key]=json_decode ($errors);

				else

					$network->save();

			}

		}

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

			...//same code than network

			

		echo json_encode(['result' => $result]);

}

So i’m obliged to do a json_decode the result of validate() to encode it again at the end of my controller… Not very smart. Do you see a better solution?

I think by default, CActiveForm::validate() does not require you to populate the model’s attributes. Its 3rd parameter ($loadInput) is by default set to true and with that, force loads all POST data with the same name as your model’s class. This works fine with single models, not sure if it negatively affects arrays of the same model. Might be safer to set that parameter to false if you are populating the attributes yourself.

For an array of models, you could probably use CActiveForm::validateTabular()

http://www.yiiframework.com/doc/api/1.1/CActiveForm#validateTabular-detail

EDIT:

You also might want to validate all your models first before saving (instead of validate -> save, validate -> save, etc), unless you are ok with some models failing validation and other going through just fine.

So you have tabular data.

I’ve never tried validateTabular() but I’m used to just concatenating the model validation outputs, something like:




public function actionSaveSiteInformation()

{

  $result = array();

  if (isset($_POST['network'])) {

    // a boolean variable holding the global validation result

    $valid = true;

    // a string variable holding the global validation errors if applicable

    $validationOutput = '';


    foreach ($_POST['network'] as $key => $network_form) {

      $network = new t_network;

      $network->attributes = $network_form;

      if (!$network->validate()) {

        $valid &= false;

        $validationOutput .= preg_replace('/network_/', 'network_' . $key . '_', CActiveForm::validate(t_network);

      }

    }


    if ($valid) {

      …

    } else {

      // echo the validation errors and end

      echo $validationOutput;

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

    }

  }

}



Thanks all, it works perfectly with validateTabular().