I’m studying the Yii CookBook and I ran into a problem: the book suggestion of a base controller is basically the following:
class PostController extends CController
{
function actions()
{
return array(
'delete' => array(
'class' => 'DeleteAction',
'modelClass' => 'Post',
);
);
}
}
class DeleteAction extends CAction
{
public $pk = 'id';
public $redirectTo = 'index';
public $modelClass;
function run()
{
if(empty($_GET[$this->pk]))
throw new CHttpException(404);
$model = CActiveRecord::model($this->modelClass)->findByPk($_GET[$this->pk]);
if(!$model)
throw new CHttpException(404);
if($model->delete())
$this->redirect($this->redirectTo);
throw new CHttpException(500);
}
}
The action delete doesn’t have any rendering, just redirect. When I tried to do the actionView I got a CException: ViewAction and its behaviors do not have a method or closure named “render”.
Yii::app()->controller ;
// if in your DeleteAction you can do this
class DeleteAction extends CAction
{
public $pk = 'id';
public $redirectTo = 'index';
public $modelClass;
// add some configurable variable
public $renderView ;
function run()
{
if(empty($_GET[$this->pk]))
throw new CHttpException(404);
$model = CActiveRecord::model($this->modelClass)->findByPk($_GET[$this->pk]);
if(!$model)
throw new CHttpException(404);
if($model->delete()){
if(isset($this->renderView)){
$this->controller->render($this->renderView);
}else{
$this->redirect($this->redirectTo);
}
}
throw new CHttpException(500);
}
}
// in CAction you can access the controller(which belong to)$this->controller ;
I was wondering if you could help me again. I’m trying to make the action Create, but for some reason the model is not being saved. It enters the $model->save() condition, but it’s not actually saved. Here is the code:
class TopicController extends DefaultController
{
public $layout='//layouts/column2';
public function actions() {
return array(
'view' => array(
'class' => 'application.controllers.actions.ViewAction',
'modelClass' => 'Topic',
),
'create' => array(
'class' => 'application.controllers.actions.CreateAction',
'modelClass' => 'Topic',
),
);
}
}
class CreateAction extends CAction {
public $modelClass;
public function run()
{
$model=CActiveRecord::model($this->modelClass);
if(isset($_POST[$this->modelClass]))
{
$model->attributes=$_POST[$this->modelClass];
if($model->save())
$this->controller->redirect(array('view','id'=>$model->id)); //it enters this if statement, but the model is not saved at all. The redirection works, but since the model was not saved, the id is null and therefore it goes to the index action.
}
$this->controller->render('create',array(
'model'=>$model,
));
}
}
The model is correctly instantiated and populated (as far as I can tell). I executed a print_r and it returned the model array:
I’m even more intrigued by this. I just managed to create the UpdateAction and it’s pretty much the same of the create, except that in one the model will be loaded and in the other the model will be instantiated. For my surprise, the update action worked.
class UpdateAction extends DefaultAction {
public $modelClass;
function run($id) {
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST[$this->modelClass]))
{
$model->attributes=$_POST[$this->modelClass];
if($model->save())
$this->controller->redirect(array('view','id'=>$model->id));
}
$this->controller->render('update',array(
'model'=>$model,
));
}
}
The method loadModel is in the DefaultAction class, which extends from CAction. Why would this work and the createAction won’t?