January 29th, 2022 by Alex Garrett-Smith

Clear orderBy in Laravel's Eloquent Builder

If you've tried to use 'orderBy' on a previously ordered query in Laravel, you'll probably find it doesn't work. There's a great reason for that, which we'll explain at the end of the post.

Let's first tackle how to clear (or reorder) builder queries.

Clearing orders in Laravel's Query Builder

Imagine we have a simple relationship on a User model to a Post relationship.

public function posts()
{
return $this->hasMany(Post::class)->latest();
}

We included latest here, because we probably always want to show the latest articles first. latest is a scope that uses orderBy behind the scenes (orderBy('created_at', 'desc')).

Now if we wanted to specify a different order from this relationship, this won't work.

$user->posts()->orderBy('updated_at', 'desc')->get();

The result from the above will still be ordered by created_at.

Reordering to the rescue

In March 2020, a reorder method was added to the query builder. Let's add it in.

$user->posts()->reorder()->orderBy('updated_at', 'desc')->get();

The reorder method removes any previously set orderBy orders from the builder, effectively meaning you're starting fresh. So now, our new orderBy in the above example will work.

You can also specify the re-ordering directly within that method. So, we could shorten the above to the following.

$user->posts()->reorder('updated_at', 'desc')->get();

That's a bit cleaner than wiping the ordering and then resetting it!

Why doesn't orderBy automatically reset ordering anyway?

In SQL, you can specify multiple orders anyway, so it makes complete sense that orderBy just appends the ORDER BY clause.

The issue is when you explicitly want to change the ordering.

So, the default functionality of orderBy makes complete sense. We just needed a way to wipe it and start fresh if we'd previously defined an order by clause.

I hope that helps! Happy ordering.