Home » Php » php – How to Paginate Multiple Models in Laravel

php – How to Paginate Multiple Models in Laravel

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have a search method that searches multiple models. For simplicity I’ve added two models that I am searching.

I would like to combine the two models to paginate their results.

Here is what I am currently doing.

public function search(Request $request)
{
    $query = $request->get('q');
    $threads = Thread::where('title', 'LIKE', "%{$query}%")->get();
    $posts = Post::where('body', 'LIKE', "%{$query}%")->get();
    $results = array_merge($threads->toArray(), $posts->toArray());
    $results = new Paginator($results, 10);

    return view('pages.search', compact('query', 'results'));
}

This works, but I feel like this is really inefficient and could be improved. Is there a better way to do this?

How to&Answers:

Try this controller,

<?php namespace App\Http\Controllers;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class SearchController extends Controller {
 public function search(Request $request){
    $query = $request->get('q');
    $threads = Thread::where('title', 'LIKE', "%{$query}%")->get();
    $posts = Post::where('body', 'LIKE', "%{$query}%")->get();
    $searchResults = array_merge($threads->toArray(), $posts->toArray());
    //Get current page form url e.g. &page=6
    $currentPage = LengthAwarePaginator::resolveCurrentPage();

    //Create a new Laravel collection from the array data
    $collection = new Collection($searchResults);

    //Define how many items we want to be visible in each page
    $perPage = 10;

    //Slice the collection to get the items to display in current page
    $currentPageSearchResults = $collection->slice($currentPage * $perPage, $perPage)->all();

    //Create our paginator and pass it to the view
    $paginatedSearchResults= new LengthAwarePaginator($currentPageSearchResults, count($collection), $perPage);

    return view('pages.search', compact('query', '$searchResults'));
 }
}

In Your view, search.blade.php

<?php echo $query->render(); ?>

Reference

Answer:

based on @Vinod VT

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;


$current_page = LengthAwarePaginator::resolveCurrentPage();
$per_page = 2;

$model_1 = Model1::where()
    ->skip(($current_page - 1) * $per_page)
    ->limit(5)
    ->latest()
    ->get();

$model_2 = Model2::where()
    ->skip(($current_page - 1) * $per_page)
    ->limit(5)
    ->latest()
    ->get();

$model_3 = Model3::where()
    ->skip(($current_page - 1) * $per_page)
    ->limit(5)
    ->latest()
    ->get();

$all_models = (collect([$model_1, $model_2, $model_3]))->flatten(0);
$collection = (new Collection($all_models))->sortByDesc('id');

$all_three_types_of_models = $collection->slice(($current_page - 1) * $per_page, $per_page)->all();

$all_models = new LengthAwarePaginator($all_three_types_of_models, count($collection), $per_page);
$all_models->withPath('');

// in blade view
{{ $all_models->render() }}

Answer:

You can check ‘DataTables’ to easy paginate data from front-end side.
https://datatables.net/