如何在Laravel中对一组对象进行分页?

时间:2014-11-21 15:37:04

标签: laravel-4 pagination pivot-table

我正在使用Laravel 4.2构建应用程序。我有units的模型和users以及数据透视表user_units的模型。此应用程序中的每个用户都可以选择一个单元并将其添加到他喜欢的列表中,然后他可以将此单元作为广告发布。

我想选择所有用户发布的所有单元

user_units(pivot)表格包含以下列:

id   
user_id 
unit_id 
publish      
adtype       
addinfo          
created_at  
updated_at

使用模型上的关系方法

public function users() {
    return $this->belongsToMany('User', 'user_units')
                ->withPivot('id','publish', 'adtype', 'addinfo');
}

public function units() {
    return $this->belongsToMany('Unit', 'user_units')
                ->withPivot('id','publish', 'adtype', 'addinfo');
}

我的查询选择所有用户的所有已发布单位

// Get all published units by users for sale. 
    $users = User::all();
    $publishedSaleUnits = [];
    foreach($users as $user){
        $userUnits = $user->units()->orderBy('adtype', 'desc')->get();
        if(count($userUnits)){
            foreach($userUnits as $unit){
                if($unit->pivot->publish == 1 && $unit->unit_purpose_id == 1){
                    if( $unit->pivot->adtype ){
                        //push all featured ads onto the beginning of array
                        array_unshift($publishedSaleUnits, $unit);
                    }else{
                        //push all normal ads onto the end of array
                        array_push($publishedSaleUnits, $unit);
                    }
                }
            }
        }
    }

现在我得到了结果,但我不能对结果使用分页,因为它是一组对象。

那么有没有更好的解决方案让用户通过分页获得所有已发布的单元?

4 个答案:

答案 0 :(得分:4)

您查询数据的方法效率极低。在一个查询中获取您的数据。嵌套遍历不仅难以阅读,而且还是性能杀手。

对于分页问题:

Laravel提供Pagignator工厂。有了它,您将能够使用自己的数据构建自己的Paginator。

就像

一样简单
$units = Paginator::make($unit, count($unit), 10);

如果你正在使用Facade。否则Illuminate\Pagination\Factory是您要找的班级。

答案 1 :(得分:1)

根据本文 https://www.itsolutionstuff.com/post/how-to-create-pagination-from-array-in-laravelexample.html

您可以通过创建自定义方法并使用LengthAwarePaginator对数组进行分页

namespace App\Http\Controllers;
  
use Illuminate\Http\Request;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Illuminate\Pagination\LengthAwarePaginator;
  
class PaginationController extends Controller
{
    public function index()
    {
        $myArray = [
            ['id'=>1, 'title'=>'Laravel CRUD'],
            ['id'=>2, 'title'=>'Laravel Ajax CRUD'],
            ['id'=>3, 'title'=>'Laravel CORS Middleware'],
        ];
  
        $data = $this->paginate($myArray);
        return view('paginate', compact('data'));
    }
   
    public function paginate($items, $perPage = 5, $page = null, $options = [])
    {
        $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
        $items = $items instanceof Collection ? $items : Collection::make($items);
        return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
    }
}

答案 2 :(得分:0)

我得到了一个更好的分页数组结果解决方案,我找到了答案here

Paginator::make函数我们只需传递所需的值而不是所有值。因为paginator::make函数只显示发送给它的数据。要将正确的偏移分页数据发送到paginator::make,应遵循以下方法

    $perPage = 5;   
    $page = Input::get('page', 1);
    if ($page > count($publishedSaleUnits) or $page < 1) { $page = 1; }
    $offset = ($page * $perPage) - $perPage;
    $perPageUnits = array_slice($publishedSaleUnits,$offset,$perPage);
    $pagination = Paginator::make($perPageUnits, count($publishedSaleUnits), $perPage);

答案 3 :(得分:0)

您可以使用自己的数组尝试我的代码,

$page = isset($request->page) ? $request->page : 1; // Get the page=1 from the url
$perPage = $pagination_num; // Number of items per page
$offset = ($page * $perPage) - $perPage;

$entries =  new LengthAwarePaginator(
    array_slice($contact_list, $offset, $perPage, true),
    count($contact_list), // Total items
    $perPage, // Items per page
    $page, // Current page
    ['path' => $request->url(), 'query' => $request->query()] // We 
       need this so we can keep all old query parameters from the url
);