Одним из преимуществ Yii фреимворка является наличие gii — генератора, который умеет генерировать модели, формы, контроллеры и даже серию файлов Crud-операций для объектов модели. Такая генерация упрощает разработку, тк вся рутинная работа уже сделана за вас, но создает большое количество дублирования в коде. Избавиться от которого я предлагаю за счет переноса повторяющихся кусков кода в базовую модель и базовый контроллер.
Создадим базовый контроллер отнаследованный от CController, у меня он называется просто Controller. Фаил базового контроллера помещаем в папку protected/components
class Controller extends CController
{
public function crudSearch($class)
{
$model=new $class('search');
$model->unsetAttributes();
if(isset($_GET[$class]))
$model->attributes=$_GET[$class];
return $model;
}
public function loadModel($id, $class)
{
$model=$class::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
}
Теперь все контроллеры должны наследоваться от базового
class SiteController extends CController
class SiteController extends Controller
Теперь создадим базовую модель, отнаследованную от CActiveRecord. Я назвала ее BaseModel и поместила в папку protected/components
class BaseModel extends CActiveRecord
{
public function saveAttributes($attributes)
{
$this->attributes = $attributes;
return $this->save();
}
public function saveFromPost($param)
{
if(isset($_POST[$param]))
{
if($this->saveAttributes($_POST[$param]))
return true;
}
return false;
}
public function getAttributeByPk($id, $atribute)
{
$result = $this->findByPk($id);
if(is_object($result)) return $result->$atribute;
else return '';
}
}
Базовая модель пока содержит всего 3 незаменимых метода: saveAttributes, saveFromPost и getAttributeByPk. Теперь все модели должны наследоваться от базовой модели
class Country extends CActiveRecord
class Country extends BaseModel
Сравним результат 🙂
Вот как выглядит типичный контроллер, сгенерированный с помощью gii
public function actionAdmin()
{
$model=new Country('search');
$model->unsetAttributes();
if(isset($_GET['Country']))
$model->attributes=$_GET['Country'];
$this->render('admin',array(
'model'=>$model,
));
}
public function actionCreate()
{
$model=new Country;
if(isset($_POST['Country']))
{
$model->attributes=$_POST['Country'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
public function actionUpdate($id)
{
$model=$this->loadModel($id);
if(isset($_POST['Country']))
{
$model->attributes=$_POST['Country'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
}
А вот так выглядит тот же код после переноса повторяющихся кусков в базовые модель и контроллер:
public function actionAdmin()
{
$model = $this->crudSearch('Country');
$this->render('country',array(
'model'=>$model,
));
}
public function actionCreate()
{
$model= new Country();
if($model->saveFromPost('Country'))
$this->redirect('/admin/country');
$this->render('createCountry',array(
'model'=>$model,
));
}
public function actionUpdate($id)
{
$model=$this->loadModel($id);
if($model->saveFromPost('Country'))
$this->redirect('/admin/country');
$this->render('update',array(
'model'=>$model,
));
}