Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] Add the ability to remove orders from the query builder #32186

Merged
merged 2 commits into from
Mar 31, 2020
Merged

[7.x] Add the ability to remove orders from the query builder #32186

merged 2 commits into from
Mar 31, 2020

Conversation

reinink
Copy link
Contributor

@reinink reinink commented Mar 31, 2020

[Replaces #32176]

It's really nice to be able to define default orders on models and relationships. For example:

class Account extends Model
{
    public function users()
    {
        return $this->hasMany(User::class)->orderBy('name');
    }
}

Now when you access $account->users, the users will be sorted properly. And the same goes for if you use the $account->users() query builder. Nice. 👍

However, this can be problematic if you ever need to order the relationship by something else. For example:

// Try to order by the emails, and not the name
// This will not work. It will reorder by name first, then email
$users = $account->users()->orderBy('email');

Because of the default orderBy() on the relationship, this will still first sort by the name, and then by the email, which may not be desirable.

This happens because new orders get added to the query builder, they do not replace existing orders. And that's good behaviour. But then how do you handle those situations where you really do want to remove the default order by? Right now you'd have to stop using the relationship, and just use the model directly, which isn't ideal.

This PR adds a very simple reorder($column = null, $direction = null) method to the query builder that lets you quickly remove all the existing orders, and optionally add a new one. Here's how you would use it:

// Remove the existing "name" order, and then order by "email".
$users = $account->users()->reorder('email');

// Remove the existing "name" order, and then order using a scope
$users = $account->users()->reorder()->orderBySomeScope();

This syntax is inspired by the Rails reorder method, which does the same thing.

@taylorotwell taylorotwell merged commit 3a3547e into laravel:7.x Mar 31, 2020
@taylorotwell
Copy link
Member

Thanks! Could you PR a quick change to laravel/docs when you get a chance.

imacrayon pushed a commit to imacrayon/framework that referenced this pull request Mar 31, 2020
…l#32186)

* Add the ability to remove orders from the query builder

* Update Builder.php

Co-authored-by: Taylor Otwell <taylor@laravel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants