问题
I'm building an application using Laravel 4.2. I have a model for units
and another for users
and pivot table user_units
. Every user in this application can select a unit and add it to his favorite list then he can publish this unit with his information as an ad.
I want to select all units published by all users
The user_units
(pivot) table has the following columns:
id
user_id
unit_id
publish
adtype
addinfo
created_at
updated_at
With relations methods on models
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');
}
My query to select all published units by all users
// 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);
}
}
}
}
}
Now I got the result but I can't use pagination with results because it's an array of objects.
So is there any better solution to get all published units by user with pagination?
回答1:
Your approach to query the data is extremely inefficient. Fetch your data in one query. Nested traversing is not only hard to read but also a performance killer.
To the pagination problem:
Laravel provides a Pagignator Factory. With it you will be able to build your own Paginator with your own data.
It's as easy as
$units = Paginator::make($unit, count($unit), 10);
if you're using the Facade. Otherwise Illuminate\Pagination\Factory
is the class you are looking for.
回答2:
I got a better solution to paginate array result and I found the answer here
Paginator::make
function we need to pass only the required values instead of all values. Because paginator::make
function simply displays the data send to it. To send the correct offset paginated data to the paginator::make
, the following method should be followed
$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:
You can try my code with your own array,
$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
);
来源:https://stackoverflow.com/questions/27064953/how-can-i-paginate-an-array-of-objects-in-laravel