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?
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-1) * $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
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() }}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With