2014-10-15 15 views
7

Tôi đang sử dụng Laravel và MySQL, và tôi có một bảng bài đăng đại diện cho bài đăng mà người dùng có thể nhận xét, bây giờ tôi muốn đặt bài đăng theo số lượng nhận xét của mỗi bài đăng trong tăng dần/giảm dần thứ tự, làm thế nào để làm điều này trong Laravel? Tôi không muốn thêm một trường trong bảng bài để theo dõi số lượng nhận xét của mỗi bài đăng, bởi vì việc cập nhật trường đó theo cách thủ công mỗi lần nhận xét hoặc nhận xét của nhận xét được thêm vào/xóa ổ đĩa của tôi ...Laravel MySQL orderBy đếm

Đây là cách tôi tạo bài viết của tôi bảng và comments bảng:

Schema::create('posts', function($table) { 
    $table->increments('id'); 
    $table->string('title', 100)->unique(); 
    $table->string('content', 2000); 
    $table->timestamps(); 
}); 
Schema::create('comments', function($table) { 
    $table->increments('id'); 
    $table->string('content', 2000); 
    $table->unsignedInteger('post_id'); 
    $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade')->onUpdate('cascade'); 
    $table->unsignedInteger('parent_id')->nullable(); 
    $table->foreign('parent_id')->references('id')->on('comments')->onDelete('cascade')->onUpdate('cascade'); 
    $table->timestamps(); 
}); 

và đây là cách tôi mối quan hệ thiết lập giữa các bài viết và ý kiến ​​trong mô hình bài viết của tôi:

public function comments() { 
    return $this->hasMany('Comment', 'post_id'); 
} 

Và trong mô hình Comment:

public function post() { 
    return $this->belongsTo('Post', 'post_id'); 
} 

Trả lời

4

Bạn có thể làm điều đó như bạn đã chỉ ra nhưng bây giờ bạn nhận được tất cả các mục từ cơ sở dữ liệu. Nếu bạn sẽ có 100 bài viết mỗi với 100 ý kiến, bạn sẽ nhận được 10000 hàng từ cơ sở dữ liệu của bạn chỉ để sắp xếp bài viết của bạn (tôi giả sử bạn không muốn hiển thị những bình luận đó khi sắp xếp).

Bạn có thể thêm vào mô hình bài viết của bạn:

public function commentsCountRelation() 
{ 
    return $this->hasOne('Comment')->selectRaw('post_id, count(*) as count') 
     ->groupBy('post_id'); 
} 

public function getCommentsCountAttribute() 
{ 

    return $this->commentsCountRelation ? 
     $this->commentsCountRelation->count : 0; 
} 

và bây giờ bạn có thể sử dụng:

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

để sắp xếp tăng dần hoặc

$posts = Post::with('commentsCount')->get()->sortBy(function($post) { 
    return $post->comments_count; 
}, SORT_REGULAR, true); 

để sắp xếp giảm dần.

Bằng cách sử dụng sortBy và sau reverse không phải là một ý tưởng tốt, bạn nên sử dụng các thông số để SortBy như tôi đã giới thiệu

+0

Cảm ơn, tôi có thể thêm vào giả định của bạn, làm thế nào bạn sẽ phân trang bài viết SAU KHI phân loại chúng bằng cách sử dụng -> paginate ($ perPage)? – dulan

+0

@dulan Đó có thể là một vấn đề nhưng tôi không phải chuyên gia Eloquent. Bạn có thể đặt một câu hỏi mới, có thể ai đó khác có giải pháp khác hoặc biết cách xử lý phân trang trong trường hợp này. Giải pháp đơn giản nhất là thêm cột truy cập như bạn đã nói lúc đầu và thêm trình kích hoạt vào cơ sở dữ liệu để cập nhật số này nhưng có thể cũng có các giải pháp khác. –

+0

Tôi đang sử dụng sự kiện mô hình Laravel thay vì kích hoạt cơ sở dữ liệu, lý do tôi nói theo dõi số lượng bình luận theo cách thủ công là vì tôi đang sử dụng onDelete ('cascade'), vì vậy nếu nhận xét bị xóa, tất cả nhận xét con của nó đã bị xóa , sau đó tôi phải tính toán có bao nhiêu nhận xét con, nhận xét, lặp lại, đệ quy và bất cứ điều gì. Các sự kiện mô hình chỉ kích hoạt một lần cho nhận xét gốc bị xóa, nó không kích hoạt cho thác ... – dulan

1

Tôi nghĩ rằng tôi đã tìm ra một cách giải quyết:

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

này một đơn hàng bằng của số ý kiến ​​ascendingly, nếu bạn muốn đặt hàng bởi nó giảm dần, làm điều này:

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

này tuyệt vời. Tôi đã bỏ lỡ() về số lượng của mình, vì vậy tôi đã chỉnh sửa nhận xét của mình. –

+0

Nó sẽ không hoạt động nếu có một phân trang. – zennin