Одним из преимуществ 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, )); }