Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sortable Laravel Package

jedrzej/sortable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Run composer require jedrzej/sortable:0.0.12 in your Laravel project root.

  2. Apply Trait Add SortableTrait to your Eloquent model:

    use Jedrzej\Sortable\SortableTrait;
    
    class Post extends Model
    {
        use SortableTrait;
    
        public $sortable = ['title', 'created_at', 'updated_at'];
    }
    
  3. First Use Case Pass a sort query parameter in your API or web request (e.g., ?sort=title,-created_at). The package automatically applies sorting to your query results.


Implementation Patterns

Core Workflow

  1. Define Sortable Fields Use either $sortable property or getSortableAttributes() method to specify allowed sort fields. Example:

    public function getSortableAttributes()
    {
        return ['name', 'price', 'published_at'];
    }
    
  2. Request Handling The package reads the sort parameter from the request (e.g., ?sort=price,-published_at).

    • Format: field1,field2,-field3 (ascending/descending).
    • Default: Falls back to model’s default order if sort is missing.
  3. Integration with Queries Use the trait in controllers or repositories:

    $posts = Post::sortable()->get(); // Applies sorting from request
    

    Or chain with other query methods:

    $posts = Post::where('status', 'published')->sortable()->paginate(10);
    
  4. API/Resource Layer Document the sort parameter in your API specs (e.g., Swagger/OpenAPI):

    parameters:
      - in: query
        name: sort
        schema:
          type: string
          example: "title,-created_at"
    
  5. Frontend Integration

    • Dynamic Sorting: Use JavaScript to update the sort parameter (e.g., with URLSearchParams). Example:
      const sortBy = (field) => {
          const params = new URLSearchParams(window.location.search);
          params.set('sort', field.startsWith('-') ? field : field);
          window.location.search = params.toString();
      };
      
    • UI Indicators: Highlight sortable columns in tables (e.g., with icons for ascending/descending).

Gotchas and Tips

Pitfalls

  1. Invalid Sort Fields

    • Issue: Passing a non-sortable field (e.g., ?sort=non_existent) throws an exception.
    • Fix: Use try-catch or validate the sort parameter in middleware:
      if (!$model->isSortable($request->sort)) {
          abort(400, 'Invalid sort field');
      }
      
  2. Case Sensitivity

    • Issue: Sorting on case-sensitive fields (e.g., name) may behave unexpectedly.
    • Fix: Use database collations or Laravel’s orderByRaw:
      public function getSortableAttributes()
      {
          return ['name' => 'LOWER(name)']; // Custom sorting logic
      }
      
  3. Performance

    • Issue: Sorting on non-indexed fields (e.g., body) is slow for large datasets.
    • Fix: Add database indexes or limit sortable fields to indexed columns.
  4. Default Order Overrides

    • Issue: The sort parameter overrides the model’s default setDefaultOrder().
    • Fix: Explicitly set defaults in the trait or use middleware to merge logic.

Debugging

  1. Log Sort Queries Enable Laravel query logging to verify sorting:

    DB::enableQueryLog();
    $posts = Post::sortable()->get();
    dd(DB::getQueryLog());
    
  2. Check Request Parsing Debug the sort parameter parsing:

    $sortable = new \Jedrzej\Sortable\Sortable($model, $request->sort);
    dd($sortable->getSorts());
    

Extension Points

  1. Custom Sort Logic Override the applySort method in your model:

    public function applySort($query, $sorts)
    {
        foreach ($sorts as $field => $direction) {
            if ($field === 'custom') {
                $query->orderByRaw('LENGTH(body) ' . $direction);
            } else {
                $query->orderBy($field, $direction);
            }
        }
    }
    
  2. Dynamic Sortable Fields Fetch sortable fields from a database table or config:

    public function getSortableAttributes()
    {
        return Config::get('app.sortable_fields.' . $this->type);
    }
    
  3. Integration with Pimpable Combine with Pimpable for unified filtering/sorting/eager-loading:

    use Jedrzej\Pimpable\PimpableTrait;
    
    class Post extends Model
    {
        use PimpableTrait;
    
        protected $pimpable = [
            'sortable' => ['title', 'created_at'],
            'searchable' => ['title', 'body'],
            'withable' => ['author', 'comments']
        ];
    }
    
  4. API Versioning Use middleware to restrict sortable fields per API version:

    public function handle($request, Closure $next)
    {
        $model = new Post();
        $allowedFields = config("api.v1.sortable_fields");
        $model->setSortable($allowedFields);
        return $next($request);
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui