laravel 过滤分页的 eloquent 集合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29843250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:26:10  来源:igfitidea点击:

filtering a paginated eloquent collection

laravellaravel-4eloquent

提问by MrFoh

I am trying to filter a paginated eloquent collection, but whenever I use any of the collection methods, I lose the pagination.

我正在尝试过滤分页的 eloquent 集合,但是每当我使用任何集合方法时,我都会丢失分页。

$models = User::orderBy('first_name','asc')->paginate(20);

$models = $models->each(function($model) use ($filters) {
    if(!is_null($filters['type'])) {
        if($model->type == $filters['type'])
            return $model;
    }

    if(!is_null($filters['state_id'])) {
        if($model->profile->state_id == $filters['state_id'])
            return $model;
    }

    if(!is_null($filters['city_id'])) {
        if($model->profile->city_id == $filters['city_id'])
            return $model;
    }
});

return $models;

I am working with Laravel 4.2, is there any way to persist the pagination?

我正在使用 Laravel 4.2,有什么办法可以坚持分页吗?

回答by Mysteryos

Expanding on mininoz's answer with your specific case:

根据您的具体情况扩展 mininoz 的答案:

//Start with creating your object, which will be used to query the database

$queryUser = User::query();

//Add sorting

$queryUser->orderBy('first_name','asc');

//Add Conditions

if(!is_null($filters['type'])) {
    $queryUser->where('type','=',$filters['type']);
}

if(!is_null($filters['state_id'])) {
    $queryUser->whereHas('profile',function($q) use ($filters){
        return $q->where('state_id','=',$filters['state_id']);
    });
}

if(!is_null($filters['city_id'])) {
    $queryUser->whereHas('profile',function($q) use ($filters){
        return $q->where('city_id','=',$filters['city_id']);
    });
}

//Fetch list of results

$result = $queryUser->paginate(20);

By applying the proper conditions to your SQL query, you are limiting the amount of information that comes back to your PHP script, and hence speeding up the process.

通过对 SQL 查询应用适当的条件,可以限制返回到 PHP 脚本的信息量,从而加快进程。

Source: http://laravel.com/docs/4.2/eloquent#querying-relations

来源:http: //laravel.com/docs/4.2/eloquent#querying-relations

回答by Robin De Schepper

None of the answers provide an answer to the actual question, which is possible in Laravel 5.2+:

这些答案都没有提供实际问题的答案,这在 Laravel 5.2+ 中是可能的:

How to filter the underlying collection of a Paginator without losing the Paginator object

如何在不丢失分页器对象的情况下过滤分页器的底层集合

The Paginator is built on an underlying collection, but indeed when you use any of the inherited Collectionmethods they return the underlying collection and not the full Paginator object: collection methods return collections for chaining together collection calls.

Paginator 建立在底层集合上,但实际上,当您使用任何继承的Collection方法时,它们返回底层集合而不是完整的 Paginator 对象:集合方法返回用于将集合调用链接在一起的集合。

But you can eject, modify and inject the collection as follows:

但是您可以按如下方式弹出、修改和注入集合:

$someFilter = 5;
$collection = $paginator->getCollection();
$filteredCollection = $collection->filter(function($model) use ($someFilter) {
  return $model->id == $someFilter;
});
$paginator->setCollection($filteredCollection);

回答by Margus Pala

paginate() is function of Builder. If you already have Collection object then it does not have the paginate() function thus you cannot have it back easily.

paginate() 是 Builder 的函数。如果您已经拥有 Collection 对象,则它没有 paginate() 函数,因此您无法轻松取回它。

One way to resolve is to have different builder where you build query so you do not need to filter it later. Eloquent query builder is quite powerful, maybe you can pull it off.

一种解决方法是使用不同的构建器来构建查询,这样您以后就不需要对其进行过滤。Eloquent 查询构建器非常强大,也许你可以把它拉下来。

Other option is to build your own custom paginator yourself.

另一种选择是自己构建自己的自定义分页器。

回答by mininoz

You can do some query on your model before do paginate.

在进行分页之前,您可以对模型进行一些查询。

I would like to give you some idea. I will get all users by type, sortthem and do paginateat the end. The code will look like this.

我想给你一些想法。我会得到all users by typesort他们并paginate在最后做。代码将如下所示。

$users = User::where('type', $filters['type'])->orderBy('first_name','asc')->paginate(20);

source: http://laravel.com/docs/4.2/pagination#usage

来源:http: //laravel.com/docs/4.2/pagination#usage

回答by Adrián Silvestre

This was suitable for me;

这很适合我;

$users = User::where('type', $filters['type'])->orderBy('first_name','asc')->paginate(20);

if($users->count() < 1){
  return redirec($users->url(1));
}