Helpex - Trao đổi & giúp đỡ Đăng nhập
14

Tôi có một hàm chung cung cấp cho tôi các tập truy vấn chung, giống như:

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');
  }
}

Hàm này được sử dụng ở mọi nơi trong dự án của tôi, nhưng ở một điểm cụ thể, tôi cần sử dụng bộ truy vấn này nhưng thay đổi ORDER BY, giống như sau:

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

Nếu tôi chạy mã này, ORDER BY sẽ chỉ thêm vào trước đó và tạo ra một truy vấn không hợp lệ, vì "somefield" không nằm trên các trường ĐÃ CHỌN. I E:

SELECT singlefield FROM table ORDER BY somefield ASC, singlefield ASC

Làm cách nào để xóa đơn hàng Bằng cách sử dụng lại các bộ truy vấn?

14 hữu ích 0 bình luận 12k xem chia sẻ
38

Tôi đồng ý rằng nên có một clearOrderBy()phương thức được thêm vào trình tạo truy vấn. Tuy nhiên, vì sổ đăng ký orderbys là tài sản công cộng Illuminate\Database\Query\Buildernên bạn thực sự có thể tự xóa nó ngay hôm nay. Bí quyết là có được quyền truy cập vào đối tượng truy vấn cơ sở:

$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');

Vào những lúc khác, chẳng hạn như khi thao tác một truy vấn quan hệ, bạn cần truy cập vào truy vấn cơ sở ( Illuminate\Database\Query\Query). Ví dụ:

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

Đó là nó. Tôi cũng dự định gửi một bài PR clearOrderBy().

38 hữu ích 0 bình luận chia sẻ
5

Trong Laravel 7, bây giờ có một phương pháp để xóa các đơn hàng khỏi trình tạo truy vấn ( # 32186 ):

public static function get_specific_field(){
    return self::get_queryset()->select('singlefield')->reorder('singlefield');
}
5 hữu ích 0 bình luận chia sẻ
2

Tại sao không "khái quát hóa" bộ truy vấn của bạn?

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);
  }
}

Sau đó, bạn có thể sử dụng

public static function get_specific_field(){
  return self::get_queryset('singlefield')->select('singlefield');
}
2 hữu ích 5 bình luận chia sẻ
2

Đây là một giải pháp đơn giản, gói nhỏ bạn có thể sử dụng nó bằng cách gọi ->clearOrdersBy() https://github.com/phpfalcon/laravel-clear-orders-by

2 hữu ích 0 bình luận chia sẻ
0

Vì đây là một câu hỏi khá cũ và có lẽ hầu hết các bạn đã nâng cấp lên Laravel 7 trở lên, nên bạn có thể sử dụng reorder()phương pháp tích hợp như @halloei đã đề cập ( # 32186 ).

Tuy nhiên, nếu bạn gặp khó khăn với Laravel phiên bản 7 dưới đây, bạn có thể tạo macro bằng cách sử dụng ý tưởng từ PR. Sau đó, bạn có thể sử dụng reorder()như bạn làm với Laravel 7. Chỉ cần đăng ký trong 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;
});
0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ php laravel eloquent , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading