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