2016-08-18 42 views
0

我有3个表格图片,评论和票数,我的票表是多态的,因为票数可以添加到图库或评论中,他们看起来像这样:按照他们得到的积分数量排序,Laravel 5.2多态关系

评论:

id 
user_id 
gallery_id 
content 

投票:

id 
user_id 
votable_type 
votable_id 
status 

状态可以是 '给予好评' 或 'downvote'。每条评论都可以是提高或降低评分。点数的评分数量是从count('upvote') - count('downvote')计算的。 votable_type可以是'应用程序\画廊'或'应用程序\评论'

我想获得所有的评论和按点数排序,评论点数最高的点在顶部。

我该怎么做?到目前为止,我这个简单的代码,但它不点的量做的投票或评论排序的任何计数:

Comment::with('votes')->with('owner') 
->where('gallery_id', $gallery->id) 
->paginate(5); 

回答

0

我想通了,这样做的伎俩:

$comments = Comment::with('votes')->with('owner') 
             ->where('gallery_id', $gallery->id) 
             ->leftJoin('votes', 'votes.votable_id', '=', 'comments.id') 
             ->selectRaw(
              'comments.*, count(case votes.status when "upvote" then 1 else null end) - count(case votes.status when "downvote" then 1 else null end) as points' 
             ) 
             ->where('votes.votable_type','App\Comment') 
             ->groupBy('comments.id') 
             ->orderBy('points', 'desc') 
             ->paginate(5); 
+0

这不会允许最近的帖子得到任何可见性,例如[这里是](https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9#7314)reddit如何做这种分类 – Meroje

0

您可以使用收藏的sortBy方法,不幸的是,你不能使用标准分页该情况:

Comment::with('votes')->with('owner') 
->where('gallery_id', $gallery->id) 
->sortBy(function($comment,$key){ 
    return $comment->votes->count(); 
}); 

这将返回一个集合,其中包含所有按票数排序的评论。

0

我想你可以用查询生成器使用连接进行分组和排序来完成此任务,但是我相信在查看代码后的半年之后,查询会相当困难并且不容易消化。

一个更简单的选择是创建一个返回的点数上Comment模型的方法,沿此线的东西:

public function getPointsAttribute() 
{ 
    $points = 0; 
    foreach ($this->votes AS $vote) { 
     $points = $vote->status == 'upvote' ? $votes + 1 : $votes - 1; 
    } 
    return $points; 
} 

再从获取他们之后的Comments收集整理数据库:

Comment::where('gallery_id', $gallery->id)->get()->sortBy('points'); 

您可以使用分页的forPage()收集,见docs

+0

将以分页的工作? –

+0

尝试在集合上使用'forPage()'方法。 – PawelMysior

+0

我还会考虑简化'Votes'模型​​,也许不是字符串'status'字段使用有符号整数'vote'字段。然后它可以有值-1或1. – PawelMysior