我有一个泛型函数,它为我提供了通用查询集,如:
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');
}
}
此功能在我的项目的任何地方都使用,但在特定点我需要使用此查询集但更改 ORDER BY,就像这样:
public static function get_specific_field(){
return self::get_queryset()->select('singlefield')->orderBy('singlefield');
}
如果我运行此代码,ORDER BY将只会追加到前一个并生成无效查询,因为“somefield”不在SELECTed字段上。即:
SELECT singlefield FROM table ORDER BY somefield ASC, singlefield ASC
如何清除orderBy以便我可以重用查询集?
答案 0 :(得分:18)
我同意应该在查询构建器中添加clearOrderBy()
方法。但是,因为orderbys的注册表是Illuminate\Database\Query\Builder
上的公共财产,您实际上可以自己清除它。诀窍是访问基本查询对象:
$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');
在其他时候,例如在操作关系查询时,您需要访问基本查询(Illuminate\Database\Query\Query
)。例如:
$query = YourModel::find(1)->load('children', function ($query) {
$query->getBaseQuery()->orders = null;
});
多数民众赞成。我计划为clearOrderBy()
提交PR。
答案 1 :(得分:2)
为什么不"泛化"你的查询集?
class Model extends Eloquent {
public static function get_queryset($orderBy = 'somefield'){
$queryset = self::where('foo','=','bar');
// Do tons of stuff with the query and then...
return $queryset->orderBy($orderBy);
}
}
然后你可以使用
public static function get_specific_field(){
return self::get_queryset('singlefield')->select('singlefield');
}
答案 2 :(得分:1)
在Laravel 7中,现在有一种方法可以从查询生成器(#32186)中删除订单:
public static function get_specific_field(){
return self::get_queryset()->select('singlefield')->reorder('singlefield');
}
答案 3 :(得分:1)
由于这是一个相当古老的问题,并且可能你们中的大多数人已经升级到 Laravel 7 及更高版本,您可以使用内置的 reorder()
方法,如@halloei 提到的 (#32186)。< /p>
但是,如果您坚持使用 Laravel bellow 版本 7,您可以使用 PR 中的想法制作一个宏。然后您就可以像在 Laravel 7 中一样使用 reorder()
。只需在 AppServiceProvider@boot
中注册即可。
\Illuminate\Database\Query\Builder::macro('reorder', function ($column = null, $direction = 'asc') {
$this->orders = null;
$this->unionOrders = null;
$this->bindings['order'] = [];
$this->bindings['unionOrder'] = [];
if ($column) {
return $this->orderBy($column, $direction);
}
return $this;
});
答案 4 :(得分:0)
这是一个简单的解决方案,只需调用->clearOrdersBy()
就可以使用它的小包装
https://github.com/phpfalcon/laravel-clear-orders-by