2017-10-11 198 views
4

我正在尝试通过投票数a Post得到Posts表。 的票被存储在另一个表中模型中的Laravel计数函数,然后sortBy count()

(Votes: post_id, user_id, vote_type) 

后型号:

class Post extends Model 
{ 
    public function user() 
    { 
     return $this->hasOne(User::class); 
    } 

    public function votes() 
    { 
     return DB::table('votes')->where('post_id','=',$this->id)->sum('vote_type'); 
    } 
} 

票数函数返回票帖子已收到的数量(存储在一个单独的表中的投票数)

现在我试图按照他们得到的票数排列所有Posts

Post::get()->sortBy('votes'); 

这将返回follwing错误:

Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

我将感谢任何帮助,以解决这个问题!

回答

4

试试看

Post::get()->sortBy(function($query){ 
return $query->votes(); 
}); 

替代

您可以使用withCount(),因为它会放置一个{relation}_count列上你的最终模型。

Post::withCount(['votes']) 
->orderBy('votes_count') 
->get() 

对于分页

参考docs的更多详细信息paginations

Post::withCount(['votes']) 
->orderBy('votes_count') 
->paginate(); 
+0

第一种解决方案不起作用:返回以下错误: '关系方法必须返回Illuminate \ Database \ Eloquent \ Relations \ Relation'类型的对象 这是因为votes()方法返回一个整数。 –

+0

现在试试我忘了()那里 –

+1

谢谢!这工作。你知道是否有任何possability分页的结果,因为它是一个集合的实例 –

-1

如果要将投票分类为属性,必须在Post模型中添加getVotesAttribute()方法以使其属性为属性。

class Post extends Model 
{ 
    public function user() 
    { 
     return $this->hasOne(User::class); 
    } 

    public function getVotesAttribute() 
    { 
     return DB::table('votes')->where('post_id','=',$this->id)->sum('vote_type'); 
    } 
} 
+0

当你将要显示上次的100个职位和他们的选票,每个帖子,你将执行此查询想要在屏幕上打印?你将如何分类? –

+0

@BartłomiejSobieszek如果你想显示100个最新帖子只是做 '邮政::上限(100) - >最新() - > - >获得() - > sortBy( '​​票');' 什么问题? –

+0

您可以通过查询执行对其进行排序,这意味着您需要执行getVotesAttribute查询100次,因为您需要为每个模型进行查询以对其进行排序。如果您没有看到问题,请尝试在单页上使用3种解决方案,并考虑为什么加载页面需要3秒以上的时间 –

0

添加下列功能后您的型号

protected static function boot() 
    { 
     parent::boot(); 
     static::addGlobalScope('voteCount', function ($builder) { 
      $builder->withCount('votes'); 
     }); 
    } 

现在,每个岗位模型中总会有一个voteCount值,您可以按上。

在你的控制器,使用方法:

Post::get()->sortBy('voteCount'); 

请记住,这将始终返回votesCount与PostModel,但我假设,因为它通常在这类应用中确实它是必需的。