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
filtering a paginated eloquent collection
提问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
回答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 Collection
methods 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
, sort
them and do paginate
at the end. The code will look like this.
我想给你一些想法。我会得到all users by type
,sort
他们并paginate
在最后做。代码将如下所示。
$users = User::where('type', $filters['type'])->orderBy('first_name','asc')->paginate(20);
回答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));
}