Error in Posting Record

I tried to insert records in two different tables, ‘tbl_message’ & ‘tbl_messagedetail’ at once in both the tables 2-2 records are inserted. I used the inbuilt function actionCreate()

Is there any error in the logic in the below code:

Need your suggestion friends.




public function actionCreate()

{

        $model = new Message;

        $modelMsgDetail = new Messagedetail;

        $messageStatus = new Status;


        // Uncomment the following line if AJAX validation is needed

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


        if(isset($_POST['Message']) && isset($_POST['Messagedetail']))

        {

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

   	     $modelMsgDetail->attributes = $_POST['Messagedetail'];

   	     // access member id

   	     $model->memberId = Yii::app()->user->id;

   	     

   	     if($model->validate() && $modelMsgDetail->validate())

   	     {

   		     if($model->save())

   		     {

   			     $modelMsgDetail->messageId = $model->messageId;

   			     if($modelMsgDetail->save())

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

   			     else

   				     die(mysql_error());

   		     }

   	     }

   	     else

   	     {

   		     die(mysql_error());    

   	     }

        }


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

   	     'model'=>$model,

   	     'modelMsgDetail'=>$modelMsgDetail,

        ));

    }



The logic is good… I’m not sure why two records are added… maybe this action is called 2 times ?

One thing… as the models are already validated you can use save(false) in both models… so that you don’t validate a second time…

I would change the die(mysql_error()); for a better user experience (if it is for you, i wont change it).Collect Model errors (http://www.yiiframework.com/doc/api/1.1/CModel#getErrors-detail) and display them user-friendly on an error page or ajax error template.

About the insertion of two records when you call the function, what does it mean, that it saves two records in each table everytime? Weird if that is like that.

And also, I would just use the following, as like mdomba says, it validates the form when you use save(); without the false parameter, so why doint it twice?

@Antonio

Your code is not good if you want to save only if both models passes validation… in your code if the $modelMsgDetail has validation errors the $model is already saved

So code in the first post is good… only if both models validates… we go to saving the data… the only thing needed is to use save(false) so that no additional validation occurs…

Oh, you are right… sorry for the pitfall

I normally use transactions to ensure processes…

@mdomba:

Even though I used save(false) in the code still more records are inserted.




if($model->validate() && $modelMsgDetail->validate())

{

      if($model->save(false))

	  {

	   	$modelMsgDetail->messageId = $model->messageId;

		   if($modelMsgDetail->save(false))

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

		   else

		     	die(mysql_error());

	   }

}



Is there any connection with the relationship which I had made with the tables??




'messageDetail'=>array(self::HAS_MANY,'Messagedetail','messageId'),

'messageStatus'=>array(self::BELONGS_TO,'Status','statusId'),



@Antonio Ramirez:

In this case, how can I use the transactions? If I can get example regarding this it would be clear for me, as I am new with this framework.

Hi there, I explain how transactions may apply on your scenario, nevertheless, I think your problem is other, it is very weird that you insert two records everytime. Have you tested the number of times that function is called? Could you set your CWebLogRoute (http://www.yiiframework.com/wiki/114/how-to-log-and-debug-variables-using-cweblogroute/ or http://www.yiiframework.com/wiki/58/sql-logging-and-profiling-in-firebug-yii-1-1/) and trace what is actually happening?


To work with transactions, first you need to make sure the database engine is innoDB (as your tables).

Then the following code is would normally use (totally untested) when I need to save models that require extra processing (saving files) or when one relates to another.




if(isset($_POST['Message']) && isset($_POST['Messagedetail']))

{

       $transaction = $model->dbConnection->beginTransaction();

	

        try

        {

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

             $modelMsgDetail->attributes = $_POST['Messagedetail'];

              //

             // access member id

             $model->memberId = Yii::app()->user->id;

             

             // you can include validation for both models here, if you do

             // do it as mdomba specified to not validate the saving  again

             // 

             if($model->save())

             {

                   $modelMsgDetail->messageId = $model->messageId;

                   if($modelMsgDetail->save())

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

                   else

                        throw new CException($MsgDetail->getErrors());

             }

             else

             {

                    throw new CException($model->getErrors()); 

             }

 

             $transaction->commit();

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

        }

        catch(CException $er){

              $transaction->rollBack();

              // do whatever you want with the errors

        }


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

             'model'=>$model,

             'modelMsgDetail'=>$modelMsgDetail,

        ));

}



I tried the above code but still get the same result. And I had tracked using ‘SQL Logging and Profiling in FireBug (Yii 1.1)’ and the application log is:




Application Log

[11:57:15.054][trace][system.db.CDbCommand] Querying SQL: SHOW COLUMNS FROM `tbl_message` in C:\xampp\htdocs\socialsite\protected\modules\message\controllers\MessageController.php (188) in C:\xampp\htdocs\socialsite\index.php (13)


[11:57:15.070][trace][system.db.CDbCommand] Querying SQL: SHOW CREATE TABLE `tbl_message` in C:\xampp\htdocs\socialsite\protected\modules\message\controllers\MessageController.php (188) in C:\xampp\htdocs\socialsite\index.php (13)


[11:57:15.099][trace][system.db.CDbCommand] Querying SQL: SELECT COUNT(*) FROM `tbl_message` `t` WHERE memberId=7 in C:\xampp\htdocs\yii\framework\zii\widgets\CBaseListView.php (105) in C:\xampp\htdocs\yii\framework\zii\widgets\CListView.php (156) in C:\xampp\htdocs\socialsite\protected\modules\message\views\message\index.php (21)


[11:57:15.107][trace][system.db.CDbCommand] Querying SQL: SELECT * FROM `tbl_message` `t` WHERE memberId=7 LIMIT 10 in C:\xampp\htdocs\yii\framework\zii\widgets\CBaseListView.php (105) in C:\xampp\htdocs\yii\framework\zii\widgets\CListView.php (156) in C:\xampp\htdocs\socialsite\protected\modules\message\views\message\index.php (21)



Very weird… Is like when you save Message it saves MessageDetail as well and viceversa isnt it?