[Solved] How To Update Specific Columns Of Table From Other Controller Actioncreate?

Hi All,

I have a tbl_scaffold with columns status_id and inspection_date that I want to be updated from InspectionController actionCreate.

The reason I want the 2 columns of tbl_scaffold to be updated as soon as I create a new inspection is because I don’t want to change it manually since the next inspection due (inspection_date) must be changed after a new inspection was created and the status (status_id) must be the same with the result of last inspection.




 /**

	 * @var private property containing the associated Scaffold model instance.

	 */

	private $_scaffold = null; 


/**

	 * Creates a new model.

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

	 */

	public function actionCreate()

	{

		$model=new Inspection;

                $model->scaffold_id = $this->_scaffold->id;

                

		// Uncomment the following line if AJAX validation is needed

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


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

		{

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

			if($model->save())

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

		}


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

			'model'=>$model,

		));

	}



The tbl_inspection has also column status_id but inspection_date is declared as public on Inspection model




class Inspection extends ScaffRegActiveRecord

{

    public $inspection_date;



and included on Inspection view/_form as date picker




<?php

/* @var $this InspectionController */

/* @var $model Inspection */

/* @var $form CActiveForm */

?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'inspection-form',

	'enableAjaxValidation'=>false,

)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<?php echo $form->errorSummary($model); ?>

	<div class="row">

		<?php echo $form->labelEx($model,'status_id'); ?>

		<?php echo $form->dropDownList($model,'status_id', $model->getStatusOptions(), array('prompt'=>'Select Status')); ?>

		<?php echo $form->error($model,'status_id'); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model,'inspection_date'); ?>

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker',

                    array(

                    'attribute' => 'inspection_date',

                    'model'=>$model,

                    'options'=> array(

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

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

                    'changeMonth' => true,

                    'changeYear' => true,

                    'showAnim' => 'slide',

                    'appendText' => '',

                    ),

                    ));

                    ?>

		<?php echo $form->error($model,'inspection_date'); ?>

	</div>

       	<div class="row buttons">

		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>

	</div>


<?php $this->endWidget(); ?>


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



The inspection is under ScaffoldContext




/**

	 * @return array action filters

	 */

	public function filters()

	{

		return array(

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

                        'scaffoldContext + create index admin', //check to ensure valid project context

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

		);

	}


/**

	 * In-class defined filter method, configured for use in the above filters() method

	 * It is called before the actionCreate() action method is run in order to ensure a proper scaffold context

	 */

	public function filterScaffoldContext($filterChain)

	{   

		//set the scaffold identifier based on either the GET input 

	    //request variables   

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

			$this->loadScaffold($_GET['pid']);   

		else

			throw new CHttpException(403,'Must specify a scaffold before performing this action.');

			

		//complete the running of other filters and execute the requested action

		$filterChain->run(); 

	}



and can only create an inspection while a valid Scaffold context is open in view.php (CDetailView)




<?php

/* @var $this ScaffoldController */

/* @var $model Scaffold */


$this->breadcrumbs=array(

	'Scaffolds'=>array('index'),

	$model->id,

);


$this->menu=array(

	array('label'=>'List Scaffold', 'url'=>array('index')),

	array('label'=>'Create Scaffold', 'url'=>array('create')),

	array('label'=>'Update Scaffold', 'url'=>array('update', 'id'=>$model->id)),

	array('label'=>'Delete Scaffold', 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->id),'confirm'=>'Are you sure you want to delete this item?')),

	array('label'=>'Manage Scaffold', 'url'=>array('admin')),

        array('label'=>'Create Inspection', 'url'=>array('inspection/create', 'pid'=>$model->id)),

);

?>


<h1>View Scaffold #<?php echo $model->id; ?></h1>


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

	'data'=>$model,

	'attributes'=>array(

                //'id',

		array(        

                    'name' => 'status_id',

                    'value' => CHtml::encode($model->getStatusText())

		),

		'inspection_date',        

	),

)); ?>


<br />

<h1>Scaffold Inspections</h1>


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

	'dataProvider'=>$inspectionDataProvider,

	'itemView'=>'/inspection/_view',

)); ?>



Note:

I removed the other columns of tbl_scaffold and tbl_inspection to shortened the codes.

I’m sure this is possible with Yii but I don’t know how to do it, please help me.

Is updating Scaffold model attributes from current Inspection view/_form while under scaffoldContext is not really posible with yii?

i think you many something looklike this…

if you want to update the status and inspection_date you can write a update query aftersave function…


public function actionCreate()

        {

                $model=new Inspection;

                $model->scaffold_id = $this->_scaffold->id;

                

                // Uncomment the following line if AJAX validation is needed

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


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

                {

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

                        if($model->save())

                     //update query.....         


$filesmodel=Scaffold::model()->updateAll(array('status'=>'1','inspection_date'=>date('Y-m-d')),"id=$model->id");

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

                }


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

                        'model'=>$model,

                ));

        }



otherwise you can write the afterFind method on model


public function afterFind()

            {

                $this->status =1;

                $this->inspection_date = date(Y-m-d', $this->created_at);

              

                parent::afterFind ();

            }

   

i am not sure but it may be helpful…

Why don’t you go with behaviors in this scenario?

it would be good approach here.So, i would recommend you to explore Behaviors in yii :)

Thank You Very Much Ankit Modi,

I played with your suggested code and the line inserted below “$model->attributes=$_POST[‘Inspection’];” on both actionCreate & actionUpdate solved my problem.




/**

	 * Creates a new model.

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

	 */

	public function actionCreate()

	{

		$model=new Inspection;

                $model->scaffold_id = $this->_scaffold->id;

                

		// Uncomment the following line if AJAX validation is needed

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


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

		{

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

                        $filesmodel = Scaffold::model()->updateAll(array('status_id'=>$model->status_id, 'inspection_date'=>$model->inspection_date), "id = $model->scaffold_id");

			if($model->save())

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

		}


		$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['Inspection']))

		{

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

                        $filesmodel = Scaffold::model()->updateAll(array('status_id'=>$model->status_id, 'inspection_date'=>$model->inspection_date), "id = $model->scaffold_id");

			if($model->save())                            

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

		}


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

			'model'=>$model,

		));

	}



Thanks codesutra for your recommendation but next time I really appreciate if you could provide an example. :)

Hi,

i think your code is incorrect bacause you want to save and update record at the same time

so please change the code after modle save if




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

save properly then after you want to update query.

Hope you got the my point.

Really i need it too.:huh:

Is it possible, Charles Dave?

yes you want to try this code


   if($model->save(false))                            

 $filesmodel = Scaffold::model()->updateAll(array('status_id'=>$model->status_id, 'inspection_date'=>$model->inspection_date), "id = $model->scaffold_id");

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

in this code first you want to insert the record and save the DB then after you want to update this.

Try to explore Cookbook a bit more you will get an idea about behavior.By the way you can refer this link

i just posted one of the reference link i hope it would be helpful.

Thanks Ankit

Thank You codeSutra