Summer sale. 20% off access to our entire library of courses.Join here →

Clear orderBy in Laravel's Eloquent Builder

January 29th, 2022

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.

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.

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!

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.

Thanks for reading! If you found this article helpful, you might enjoy our practical screencasts too.
Alex Garrett-Smith
Share :


No comments, yet. Be the first to leave a comment.