Chapter 7

I’m currently using Yii 1.1.6

I kept receiving project.update_time is not defined error. What am I doing wrong?

1211

yiierror.png

Here is my TrackStarActiveRecord




<?php





abstract class TrackStarActiveRecord extends CActiveRecord{


    /**


     * Prepares create_time, create_user_id, update_time and update_user_id attributes before performing validation 


     * */


     


     protected function beforeValidate()


     {


        if ($this->isNewRecord)


        {


            //set the create date, last updated date, and the user doing the creating


            $this->create_time = $this->update_time = new CDbExpression('NOW()');


            $this->create_user_id = $this->update_user_id = Yii::app()->user->id;            


        }


        else


        {


            //not a new record, so just set the last updated time and last updated user id


            $this->update_time = new CDbExpression('NOW()');


            $this->update_user = Yii::app()->user->id; 


        }


        


        return parent::beforeValidate();


     }





}



Here is my ProjectTest




<?php


    class ProjectTest extends CDbTestCase


    {


        public $fixtures=array


        (


            'projects' => 'Project',


            'users' => 'User',


            'projUsrAssign' => ':tbl_project_user_assignment',


        );


        


        public function testCreate()


        {


            //CREATE a new Project


            $newProject=new Project;


            $newProjectName = 'Test Project Creation';


            $newProject->setAttributes(array(


            'name' => $newProjectName,


            'description' => 'This is a test for new project creation',


           // 'create_time' => '2009-09-09 00:00:00',


           // 'create_user_id' => '1',


           //'update_time' => '2009-09-09 00:00:00',


           // 'update_user_id' => '1',


            ));


            


            //set the application user id to the first user in our user fixture data


                Yii::app()->user->setId($this->users('user1')->id);


            //set the new project triggering attribute validation            


            $this->assertTrue($newProject->save());


            //READ back the newly created Project to ensure the creation worked


            $retrievedProject=Project::model()->findByPk($newProject->id);


            $this->assertTrue($retrievedProject instanceof Project);


            $this->assertEquals($newProjectName,$retrievedProject->name);


            $this->assertEquals(Yii::app()->user->id,$retrievedProject->create_user_id);


        }


        


        public function testRead()


        {


            $retrievedProject = $this->projects('project1');


            $this->assertTrue($retrievedProject instanceof Project);


            $this->assertEquals('Test project 1',$retrievedProject->name);


        }


        


        public function testUpdate()


        {


            $project = $this->projects('project2');


            $updatedProjectName = 'Updated Test Project 2';


            $project->name = $updatedProjectName;


            $this->assertTrue($project->save(false));


            //read back the record again to ensure the update worked


            $updatedProject=Project::model()->findByPk($project->id);


            $this->assertTrue($updatedProject instanceof Project);


            $this->assertEquals($updatedProjectName,$updatedProject->name);


        }


        


        public function testDelete()


        {


            $project = $this->projects('project2');


            $savedProjectId = $project->id;


            $this->assertTrue($project->delete());


            $deletedProject=Project::model()->findByPk($savedProjectId);


            $this->assertEquals(NULL,$deletedProject);


        }


        


        public function testGetUserOptions()


        {


            $project = $this->projects('project1');


            $options = $project->userOptions;


            $this->assertTrue(is_array($options));


            $this->assertTrue(count($options) > 0);             


        }


        


        }

        



Thanks

Do you have a field called update_time in your tbl_project table?

Do you extend the Project Model class from TrackStarActiveRecord?

Yes I do have it, that’s why I felt it kind of strange.

Hmm… is it possible to create a new project in your browser? If yes, most probably something is wrong with your test database.

I back tracked to chapter 6 and just completed it. In both of my code through, I did encounter an error on the update issue,

On the contrary, I don’t get any errors on create issue.

Is this normal or could this be the cause?




Fatal error: Call to a member function getUserOptions() on a non-object in /opt/lampp/htdocs/web/protected/views/issue/_form.php on line 43



_form.php code




<div class="form">


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

	'id'=>'issue-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,'name'); ?>

		<?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>256)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'description',array('size'=>60,'maxlength'=>2000)); ?>

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

	</div>


	<div class="row">

		<?php echo $form->hiddenField($model,'project_id'); ?>

	</div>




	<div class="row">

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

		<?php echo $form->dropDownList($model,'type_id', $model->getTypeOptions()); ?>	

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

	</div>


	<div class="row">

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

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

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

	</div>


	<div class="row">

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

		<?php echo $form->dropDownList($model,'owner_id', $this->getProject()->getUserOptions()); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->dropDownList($model,'requester_id', $this->getProject()->getUserOptions()); ?>

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

	</div>


	<div class="row buttons">

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

	</div>


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


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



I guess you forgot the getProject() method in the IssueController…

Nope, I didn’t forget about it.

Could it be the cause of the changes in version 1.1.6?

NOTE:

Create Issue is WORKING.

But Update Issue is NOT.




<?php


class IssueController 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

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

		);

	}


	/**

	 * 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 Issue;

		$model->project_id = $this->_project->id;

		// Uncomment the following line if AJAX validation is needed

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


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

		{

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

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

		{

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

			if($model->save())

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

		}


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

			'model'=>$model,

		));

	}


	/**

	 * Deletes a particular model.

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

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

	 */

	public function actionDelete($id)

	{

		if(Yii::app()->request->isPostRequest)

		{

			// we only allow deletion via POST request

			$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'));

		}

		else

			throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Issue', array(

			'criteria' => array(

				'condition' => 'project_id = :projectId',

				'params' => array(':projectId' => $this->_project->id),

			),	

		));

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

			'dataProvider'=>$dataProvider,

		));

	}


	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new Issue('search');

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

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

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


		$model->project_id = $this->_project->id;

			

		$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=Issue::model()->findByPk((int)$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']==='issue-form')

		{

			echo CActiveForm::validate($model);

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

		}

	}

	/**

	* @var private property containing the associated Project model

	instance.

	*/

	private $_project = null;

	

	/**

	* Protected method to load the associated Project model class

	* @project_id the primary identifier of the associated Project

	* @return object the Project data model based on the primary key

	*/

	

	protected function loadProject($project_id)

	{

		//if the project property is null, create it based on input id

		if($this->_project===null)

		{

			$this->_project=Project::model()->findbyPk($project_id);

			

			if($this->_project===null)

			{

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

			}

		}

		return $this->_project;

	}


	/**

	* 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 project context

	*/

	public function filterProjectContext($filterChain)

	{

	//set the project identifier based on either the GET or POST input

	//request variables, since we allow both types for our actions

		$projectId = null;

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

			$projectId = $_GET['pid'];

		else

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

				$projectId = $_POST['pid'];

			$this->loadProject($projectId);

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

			$filterChain->run();

	}


	/**

	* Returns the project model instance to which this issue belongs

	*/

	public function getProject()

	{

		return $this->_project;

	}

	

	

}



hmmmm strange… have you ever compared your code with the one which comes with the book?

so far, loadmodel($id) is different in a sense that it is not null. I’ve to check the rest.

I wanted to use Yii as soon as I can, but I’m stuck with codeigniter because I’m still learning Yii.