2014-10-15 14 views
5

Tôi có bài đăng bảng và ý kiến ​​ bảng, nhận xét thuộc về bài đăng và tôi có thiết lập mối quan hệ trong mô hình Đăng và nhận xét. Tôi đã sắp xếp bài đăng theo số lượng nhận xét của mỗi bài đăng như sau:Laravel sortBy paginate

 $posts = Post::with('comments')->get()->sortBy(function($post) { 
      return $post->comments->count(); 
     }); 

Tôi tự hỏi làm cách nào để phân loại các bài đăng được sắp xếp này?

 $posts = Post::with('comments')->get()->sortBy(function($post) { 
      return $post->comments->count(); 
     })->paginate(20); 

không hoạt động và cung cấp cho tôi lỗi nói phân trang là phương pháp chưa xác định.

Trả lời

4

Tôi không biết nếu bạn có thể làm điều đó bằng hùng biện nhưng bạn có thể sử dụng tham gia cho việc này:

$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')-> 
       selectRaw('posts.*, count(comments.post_id) AS `count`')-> 
       groupBy('posts.id')-> 
       orderBy('count','DESC')-> 
       paginate(20); 

Tuy nhiên có vẻ như rằng trong trường hợp này tất cả hồ sơ được lấy từ cơ sở dữ liệu và chỉ có những hiển thị từ paginator , vì vậy nếu bạn có nhiều hồ sơ, nó lãng phí tài nguyên. Có vẻ như bạn nên làm pagination tay cho việc này:

$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')-> 
       selectRaw('posts.*, count(comments.post_id) AS `count`')-> 
       groupBy('posts.id')-> 
       orderBy('count','DESC')-> 
       skip(0)->take(20)->get(); 

sử dụng skiptake nhưng tôi không hùng biện chuyên gia và có thể có một giải pháp tốt hơn để đạt được mục tiêu của bạn, do đó bạn có thể chờ đợi và có lẽ ai đó sẽ đưa ra một câu trả lời tốt hơn .

+0

Thansk, vì vậy chỉ cần phải rõ ràng, giải pháp này sẽ không lấy tất cả các bản ghi từ cơ sở dữ liệu và sau đó sắp xếp nó ra, nó chỉ lấy 20 bản ghi ngay từ đầu phải không? – dulan

+0

@dulan, vâng, nếu chúng ta đang nói về mã thứ 2. Trong mã đầu tiên tất cả các hồ sơ sẽ được lấy từ cơ sở dữ liệu và chỉ hiển thị một số trong số chúng, do đó bạn cần chọn giải pháp thứ hai –

+0

cảm ơn vì đã sử dụng skip() –

0

Chỉ cần xóa get() trong các cuộc gọi bị xích và xem những gì bạn nhận được, phân trang sẽ thay thế get() cuộc gọi.

+0

Nó sẽ không hoạt động. 'sortBy' được sử dụng cho tập kết quả để sử dụng paginate làm cho việc sắp xếp đó sẽ chỉ được thực hiện cho 20 hàng đầu tiên chứ không phải cho tất cả các bản ghi. Đó là sự khác biệt. Đầu tiên sắp xếp sau đó phân trang không đối diện –

+0

Tôi đề nghị anh ta để loại bỏ get(), không phải để thay thế nó bằng paginate(), paginate sẽ thay thế nó một cách có chức năng nói. – cdarken

1

Điều này nghe có vẻ hiển nhiên, nhưng Eloquent sẽ không trả lại kết quả được đặt ở đây, nhưng thay vào đó nó sẽ trả về bộ sưu tập.

Nếu bạn thâm nhập vào nguồn (Builder::get gọi Builder::getFresh, trong đó kêu gọi Builder::runSelect, trong đó kêu gọi Connection::select), bạn sẽ thấy rằng đó là ý định là chỉ đơn giản là trả lại kết quả, mà sau đó được đặt vào một bộ sưu tập (trong đó có các SortBy phương pháp).

/** 
* Run a select statement against the database. 
* 
* @param string $query 
* @param array $bindings 
* @param bool $useReadPdo 
* @return array 
*/ 
public function select($query, $bindings = array(), $useReadPdo = true) 
{ 
    return $this->run($query, $bindings, function($me, $query, $bindings) use ($useReadPdo) 
    {  
    if ($me->pretending()) return array(); 

    // For select statements, we'll simply execute the query and return an array 
    // of the database result set. Each element in the array will be a single 
    // row from the database table, and will either be an array or objects. 
    $statement = $this->getPdoForSelect($useReadPdo)->prepare($query); 

    $statement->execute($me->prepareBindings($bindings)); 

    //** this is a very basic form of fetching, it is limited to the PDO consts. 
    return $statement->fetchAll($me->getFetchMode()); 
    }); 
} 

Nếu bạn muốn có pagination mà không cần nạp mỗi mục, sau đó bạn cần phải sử dụng @ giải pháp Marcin của (nhân đôi dưới đây):

$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')-> 
      selectRaw('posts.*, count(comments.post_id) AS `count`')-> 
      groupBy('posts.id')-> 
      orderBy('count','DESC')-> 
      skip(0)->take(20)->get(); 
Các vấn đề liên quan