DEV Community

Cover image for Eloquenturl: A Laravel Package to Simplify or Eliminate Query Building for URL Parameters
Don Cadavona
Don Cadavona

Posted on • Updated on

Eloquenturl: A Laravel Package to Simplify or Eliminate Query Building for URL Parameters

Eloquenturl is a Laravel package that simplifies and eliminates building of complex, cluttered and unreusable queries for filters, search, sort, scopes, pagination and more.

The name "Eloquenturl", pronounced "Eloquenterl" was derived from the term "Eloquent URL". Meaning, Laravel's Eloquent models can be queried with only URL parameters.

For example, you have a route /articles, and wish to support filtering the index results with URL parameters, /articles?search=apple&order_by=author&scope[published]=true&scope[featured]=true, without Eloquenturl, your resource controller would be something like this:

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;

class ArticlesController extends Controller
{
    public function index(Request $request)
    {
        // Initialise query
        $articles_query = Article::with('category');

        // Build the filters query

        // Filter articles by search term
        if ($request->filled('search')) {
            $articles_query->where('title', 'like', '%'.$request->search.'%')
                ->orWhereHas('category', function($query) use ($request) {
                    $query->where('name', 'like', '%'.$request->search.'%');
                });
        }

        // Filter articles by category
        if($request->filled('category')){
            // Validate the ordering parameters
            if (in_array(strtolower($request->category), $categories->pluck('slug')->toArray())) {
                $articles_query->whereHas('category', function($query) use ($request) {
                    $query->where('slug', $request->category);
                });
            }
        }

        // Filter articles by user/author's username
        if($request->filled('username')){
            $articles_query->whereHas('user', function($query) use ($request) {
                $query->where('username', $request->username);
            });
        }

        // Ugh, notice that for every field you wish to filter by,
        // you'll write code for that just like above.

        // Order articles
        if ($request->filled('order_by')) {
            // Validate the ordering parameters
            if (in_array(strtolower($request->order_by), ['title', 'published_at'])) {
                $order_by = strtolower($request->order_by);
                $order = $request->filled('order') && in_array($request->order, ['asc', 'desc']) ? strtolower($request->order) : 'asc';
                $articles_query->orderBy($order_by, $order);
            }
        } else {
            // Set default ordering
            $articles_query->orderBy('published_at', 'desc');
        }

        // Execute the query
        $articles = $articles_query->paginate();

        return view('articles.index',compact('articles'));
    }
}
Enter fullscreen mode Exit fullscreen mode

To be fare, the code above is already well written. But,

With Eloquenturl, we can make it simple, yet more powerful:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Article;
use Doncadavona\Eloquenturl\Eloquenturl;
use Illuminate\Http\Request;

class ArticlesController extends Controller
{
    public function index(Request $request)
    {
        // Simply pass the model and the request.
        $articles = Eloquenturl::eloquenturled(Article::class, $request);

        return view('articles.index', compact('articles'));
    }
}
Enter fullscreen mode Exit fullscreen mode

Please take a look at the Github Repository for installation, usage guides and more details:

https://github.com/doncadavona/eloquenturl

Credits

Eloquenturl is developed by Don Cadavona with love.

Top comments (0)