Instantly share code, notes, and snippets.

Embed
What would you like to do?
Laravel Eloquent pagination and column sorting using macros
<?php
namespace App\Providers;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\ServiceProvider;
class EloquentSortableServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Builder::macro('sort', function () {
$sort = explode(',', request()->sort, 2);
if (empty($sort[1])) {
return $this;
}
return $this->orderBy($sort[0], $sort[1]);
});
Request::macro('sortBy', function ($field) {
$query = request()->query();
// go back to the page 1 and sort by $field asc by default
if (empty($query['sort'])) {
return request()->url() . '?sort=' . $field . ',asc';
}
// 'sort' is set but the 'field' is empty ? reload
$sort = explode(',', request()->sort, 2);
if (empty($sort[1])) {
return request()->fullUrl();
}
// if the current 'order' is 'asc' then return 'desc' and so.
$sort = '?sort=' . $field . ',' . ($sort[1] == 'asc' ? 'desc' : 'asc');
return request()->url() . $sort;
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
// Create this service provider and edit your config/app.php file to add:
'providers' => [
//...
\App\Providers\EloquentSortableServiceProvider::class,
//...
]
// Usage: call sort() method before the paginate()
Route::get('/', function () {
$users = \App\User::sort()->paginate(10);
return view('users', compact('users'));
});
// Then you can easily build the links using the request() helper
// calling the sortBy() method and passing the name of the field of your table
<a href="{{request()->sortBy('name')}}">Name</a>
// Finally don't forget to add this when you call the links() method to persist the new "sort" param
{{ $users->appends(['sort' => request()->sort])->links() }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment