Базовая модель и базовый контроллер для Yii

3 сентября, 2014
Метки:

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

Метки:

Оставить комментарий

Ты будешь первым :)

Оставить комментарий:









Копирование материалов разрешено при наличии активной ссылки на источник