Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clear Laravel's orderBy

I have a generic function which gives me generic querysets, something like:

class Model extends Eloquent {
  public static function get_queryset(){
    $queryset = self::where('foo','=','bar');
    // Do tons of stuff with the query and then...
    return $queryset->orderBy('somefield');
  }
}

This function is used everywhere my project, but in a specific point I need to use this queryset but changing the ORDER BY, much like this:

public static function get_specific_field(){
  return self::get_queryset()->select('singlefield')->orderBy('singlefield');
}

If I run this code, the ORDER BY will just append onto the previous and generate an invalid query, since the "somefield" is not on the SELECTed fields. i.e.:

SELECT singlefield FROM table ORDER BY somefield ASC, singlefield ASC

How do I clear the orderBy so I can just reuse querysets?

like image 304
Rafael Sierra Avatar asked Nov 11 '14 16:11

Rafael Sierra


People also ask

How do I use orderBy in laravel eloquent?

To sort results in the database query, you'll need to use the orderBy() method, and provide the table field you want to use as criteria for ordering. This will give you more flexibility to build a query that will obtain only the results you need from the database. You'll now change the code in your routes/web.

What is default order by in laravel?

By default, Laravel Eloquent models return queries that are ordered by the id column of the model table. With this package, you can set default order by in your Eloquent model so you don't have to call the orderBy Eloquent builder.

What is global scope in laravel?

Global scopes allow you to add constraints to all queries for a given model. Laravel's own soft delete functionality utilizes global scopes to only retrieve “non-deleted” models from the database. In this article, we'll create our own global scope.


2 Answers

I agree there should be a clearOrderBy() method added to the query builder. However because the registry of orderbys is a public property on Illuminate\Database\Query\Builder you actually can clear it yourself today. The trick is getting access to the base query object:

$query = YourModel::where('status', 1)->orderBy('created_at','desc');
// ... lots of other code, something needs to reset the order by ...
$query->getQuery()->orders = null;
$query->orderBy('other_column', 'desc');

At other times, for example when manipulating a relation query, you need to get to access the base query (Illuminate\Database\Query\Query). So for example:

$query = YourModel::find(1)->load('children', function ($query) {
    $query->getBaseQuery()->orders = null;
});

Thats it. I plan to submit a PR for a clearOrderBy() as well.

like image 112
jpschroeder Avatar answered Oct 08 '22 13:10

jpschroeder


In Laravel 7, there's now a method to remove the orders from the query builder (#32186):

public static function get_specific_field(){
    return self::get_queryset()->select('singlefield')->reorder('singlefield');
}
like image 7
halloei Avatar answered Oct 08 '22 14:10

halloei