2014-06-13 15 views
17

Tôi đang cố gắng để có được những hackathons phổ biến nhất mà yêu cầu đặt hàng bởi hackathon tương ứng partipants->count(). Xin lỗi nếu đó là một chút khó hiểu.Thứ tự LarboBộ đếm mối quan hệ

Tôi có một cơ sở dữ liệu với định dạng sau:

hackathons 
    id 
    name 
    ... 

hackathon_user 
    hackathon_id 
    user_id 

users 
    id 
    name 

Mô hình Hackathon là:

class Hackathon extends \Eloquent { 
    protected $fillable = ['name', 'begins', 'ends', 'description']; 

    protected $table = 'hackathons'; 

    public function owner() 
    { 
     return $this->belongsToMany('User', 'hackathon_owner'); 
    } 

    public function participants() 
    { 
     return $this->belongsToMany('User'); 
    } 

    public function type() 
    { 
     return $this->belongsToMany('Type'); 
    } 
} 

HackathonParticipant được định nghĩa là:

class HackathonParticipant extends \Eloquent { 

    protected $fillable = ['hackathon_id', 'user_id']; 

    protected $table = 'hackathon_user'; 

    public function user() 
    { 
     return $this->belongsTo('User', 'user_id'); 
    } 

    public function hackathon() 
    { 
     return $this->belongsTo('Hackathon', 'hackathon_id'); 
    } 
} 

Tôi đã thử Hackathon::orderBy(HackathonParticipant::find($this->id)->count(), 'DESC')->take(5)->get()); nhưng tôi cảm thấy như tôi đã phạm sai lầm lớn (có thể là $ this-> id), bởi vì nó không hoạt động chút nào.

Tôi sẽ làm cách nào để tìm cách sử dụng các hackathons phổ biến nhất dựa trên số lượng người tham gia HackathonParticipant liên quan cao nhất?

Trả lời

21

Bạn sẽ có thể sử dụng các phương pháp và count() của để thực hiện điều này khá dễ dàng.

$hackathons = Hackathon::with('participants')->get()->sortBy(function($hackathon) 
{ 
    return $hackathon->participants->count(); 
}); 
+0

Làm thế nào để thay đổi asending/desecnding? – FooBar

+2

'sortBy (Đóng $ callback, $ options = SORT_REGULAR, bool $ descending = false)' Chỉ cần đặt tham số thứ 3 là true. – user3158900

+19

sắp xếp theo không làm điều đó ở cấp DB ... do đó, nó sẽ không hoạt động đúng với phân trang! Tốt cho khi bạn đang quay trở lại một bộ đầy đủ mặc dù .. –

12

Tôi có vấn đề tương tự và sử dụng sortBy() không phù hợp do phân trang, chính xác như Sabrina Gelbart đã nhận xét trong giải pháp trước. Vì vậy, tôi đã sử dụng db raw, đây là truy vấn được đơn giản hóa:

Tag::select( 
array(
    '*', 
    DB::raw('(SELECT count(*) FROM link_tag WHERE tag_id = id) as count_links')) 
)->with('links')->orderBy('count_links','desc')->paginate(5); 
+1

Giải pháp tốt nhất tôi đã tìm thấy cho các phiên bản trước của Laravel! (những cái mới có thể sử dụng withCount) Không chắc chắn nó là gì nhưng tôi đã làm: 'tag_id = tag.id' thay vì' tag_id = id' ... cũng vậy, bạn có thể đơn giản hóa điều này nhiều hơn nữa! Thay vì làm 'select' bạn chỉ có thể làm' orderByRaw ('(SELECT count (*) FROM link_tag WHERE tag_id = tag.id) dưới dạng count_links') DESC ') -> paginate (5) '.Và đối với những băn khoăn, bạn không cần '-> with' trừ khi bạn đang tải các mối quan hệ –

+0

And..you cũng có thể làm điều này trong một phạm vi nếu bạn muốn ...' Tag :: orderByLinkCount() - > paginate (5) 'sau đó trong mô hình Tag của bạn tạo 'scopeOrderByLinkCount' với tuyên bố orderByRaw bạn –

+0

tôi tin rằng nó nên được' ở ĐÂU TAG_ID = tag.id' KHÔNG' ở ĐÂU TAG_ID = id' –

0

Bạn cũng có thể sử dụng toán tử nối. Như Sabrina đã nói, bạn không thể sử dụng phân loại ở cấp db.

$hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id') 
      ->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`') 
      ->groupBy('hackathon.id') 
      ->orderBy('count','DESC') 
      ->paginate(5); 

Nhưng mã này lấy tất cả bản ghi từ cơ sở dữ liệu. Vì vậy, bạn nên phân trang theo cách thủ công.

 $hackathons = Hackathon::leftJoin('hackathon_user','hackathon.id','=','hackathon_user.hackathon_id') 
      ->selectRaw('hackathon.*, count(hackathon_user.hackathon_id) AS `count`') 
      ->groupBy('hackathon.id') 
      ->orderBy('count','DESC') 
      ->skip(0)->take(5)->get(); 

giới thiệu từ: https://stackoverflow.com/a/26384024/2186887

36

này làm việc cho tôi trong Laravel 5.3, sử dụng ví dụ của bạn:

Hackathon::withCount('participants')->orderBy('participants_count', 'desc')->paginate(10); 

Bằng cách này nó được đặt trên các truy vấn và pagination hoạt động độc đáo.

+0

Đây là một câu trả lời tốt hơn nhiều so với chấp nhận một. – tremby

Các vấn đề liên quan