Search code examples
yii2yii2-advanced-appyii2-basic-app

LIMIT is not working in ActiveDataProvider


I am using following code and the limit doesnt work. But if I see the command than it shows limit in that, but when I pass the query to ActiveDataProvider it fetch all the records:

$data= User::find()->where(['category_id'=> 5])->orderBy(['rand()' => SORT_DESC])->limit(4);

    $command = $data->createCommand();

    $data2 = $command->queryAll();// This works fine and fetch only 4 data 

    $dataProvider = new ActiveDataProvider([
        'query' => $data,

    ]); // But this displays all data without limit

What is wrong I am doing here?


Solution

  • Here is what happens when preparing models in yii\data\ActiveDataProvider:

    /**
     * @inheritdoc
     */
    protected function prepareModels()
    {
        if (!$this->query instanceof QueryInterface) {
            throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.');
        }
        $query = clone $this->query;
        if (($pagination = $this->getPagination()) !== false) {
            $pagination->totalCount = $this->getTotalCount();
            $query->limit($pagination->getLimit())->offset($pagination->getOffset());
        }
        if (($sort = $this->getSort()) !== false) {
            $query->addOrderBy($sort->getOrders());
        }
    
        return $query->all($this->db);
    }
    

    We're interested in this part:

    if (($pagination = $this->getPagination()) !== false) {
        $pagination->totalCount = $this->getTotalCount();
        $query->limit($pagination->getLimit())->offset($pagination->getOffset());
    }
    

    So as you can see if pagination is not false, limit is managed automatically.

    You can just set pagination to false and then manual setting of limit will work:

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'pagination' => false,
    ]);