过滤分页的雄辩集合

时间:2015-04-24 09:08:57

标签: laravel laravel-4 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;

我正在使用Laravel 4.2,有没有办法坚持分页?

6 个答案:

答案 0 :(得分:5)

根据您的具体案例扩展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);

通过对SQL查询应用适当的条件,您可以限制返回PHP脚本的信息量,从而加快处理速度。

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

答案 1 :(得分:1)

paginate()是Builder的功能。如果你已经有了Collection对象,那么它没有paginate()函数,因此你不能轻易地将它恢复。

解决的一种方法是在构建查询时使用不同的构建器,以便以后不需要对其进行过滤。雄辩的查询构建器功能非常强大,也许你可以将它拉下来。

其他选择是自己构建自己的自定义分页器。

答案 2 :(得分:1)

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

我想给你一些想法。我会得到all users by typesort他们并在最后做paginate。代码看起来像这样。

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

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

答案 3 :(得分:1)

我有一个场景,要求我对集合进行过滤,而我不能依赖查询生成器。

我的解决方案是实例化我自己的Paginator实例:

 $records = Model::where(...)->get()->filter(...);

 $page = Paginator::resolveCurrentPage() ?: 1;
 $perPage = 30;
 $records = new LengthAwarePaginator(
     $records->forPage($page, $perPage), $records->count(), $perPage, $page, ['path' => Paginator::resolveCurrentPath()]
 );

 return view('index', compact('records'));

然后在我的刀片模板中:

{{ $records->links() }}

答案 4 :(得分:0)

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

  

如何在不丢失Paginator对象的情况下过滤Paginator的基础集合

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

但是您可以按以下步骤弹出,修改和注入集合:

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

答案 5 :(得分:0)

这适合我;

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

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