V
V
vitovt2017-03-04 19:02:27
Yii
vitovt, 2017-03-04 19:02:27

How to make the controller thin?

I am rewriting one project in Yii2 and I want to put a lot of things into the model. Moreover, make it so that the model gives a certain data set (array or dataProvider) and the controller does not know anything about it)
In general, I am trying to write a thin controller and a thick model and I don’t understand how best to do it, I rush between several implementations.
In general, poke your fingers the coolest example of the implementation of the search, selection and output of records from the database.
1. Use the SearchModel and the search() method in which to return the dataProvider, and pass it in the controller
$items = SearchModel->search();
2. Do not use the dataProvider in the search method, but simply write something like this in the controller

$items = SearchModel::fund()->limit(...)->offset(..)->all();

and immediately define $pages and pass it all to the view.
As an example of one tutorial:
function actionIndex()
{
    $query = Article::find()->where(['status' => 1]);
    $countQuery = clone $query;
    $pages = new Pagination(['totalCount' => $countQuery->count()]);
    $models = $query->offset($pages->offset)
        ->limit($pages->limit)
        ->all();

    return $this->render('index', [
         'models' => $models,
         'pages' => $pages,
    ]);
}

3. Mix two options:
in the model make
public static function find()
    {
        return \Yii::createObject(SomeQuery::className(), [get_called_class()]);
    }

Then write SomeQuery with a method like this
public function byFilter( $params ) {
if ( $params ) {
            foreach ( $params as $k => $v ) {
                if( trim($v)!='') {
                    switch ( $k ) {

                        case 'user_id' : {
                            $this->andWhere(['user_id' => intval( $v )]);
                        } break;

......
 }

Then in the controller just call
$query = SearchModel::find()->byFilter(\Yii::$app->request->queryParams)->all();

I don’t understand how it’s better \ more correct \ then easier to maintain. I would like to make it universal, so that with an increase in loads and a change in the selection principle from the database, the controller would not be touched at all, but only the model would be changed and optimized.
Thanks =)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
AlexKuznec, 2017-03-04
@AlexKuznec

I didn’t quite understand what was needed, but in the Gii model generator, the checkbox "Generate ActiveQuery" is not for your case?

M
Maxim Fedorov, 2017-03-05
@qonand

Building queries to the database in the controller is a gross violation of the principles of MVC. The task of the controller is to process the user's request and generate a response to it. There should not be any business logic, selections and other things in the controller. Therefore, it is definitely better to use SearchModel
a couple of articles to help you:
https://habrahabr.ru/post/321050/
https://habrahabr.ru/post/322700/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question