模型中的Laravel计数函数,然后sortBy count()

时间:2017-10-11 10:27:06

标签: php mysql laravel

我正在尝试按Posts得到的票数对Post表进行排序。 投票存储在另一个表中

(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');

这将返回以下错误:

  

关系方法必须返回类型为Illuminate \ Database \ Eloquent \ Relations \ Relation

的对象

我会感谢任何帮助解决这个问题!

3 个答案:

答案 0 :(得分:4)

试一试

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

<强>替代

您可以使用withCount(),因为它会在您生成的模型上放置{relation}_count列。

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

For Pagination

有关分页的详细信息,请参阅docs

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

答案 1 :(得分:0)

在帖子模型中添加以下功能

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

现在,您的每个帖子模型将始终具有voteCount值,您可以对其进行排序。

在您的控制器中,使用:

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

请记住,这将始终返回带有PostModel的votesCount,但我认为这将是必需的,因为它通常在这种应用程序中。

答案 2 :(得分:-1)

如果您想将投票作为属性进行排序,则必须通过在getVotesAttribute()模型中添加Post方法使其成为属性。

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');
    }
}