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?
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.
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);
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