从查询中获取最受欢迎的新闻

时间:2016-08-04 18:34:16

标签: ruby-on-rails ruby

有两种型号:

# == Schema Information
#
# Table name: news
#
#  id         :integer          not null, primary key
#  title      :string           not null
#  content    :text             not null
#  scope      :string           not null
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  person_id  :integer          not null

# == Schema Information
#
# Table name: likes
#
#  id        :integer          not null, primary key
#  like      :boolean
#  person_id :integer          not null
#  news_id   :integer          not null

关系

news has many likes
like belongs to news

我希望从查询中获得最受欢迎的新闻。查询应该从like等于false中减去等于true的数量。最高的数字是最受欢迎的新闻。 我尝试了什么:

@count_true_likes = Like.where('likes.like = ?', true).group(:news_id).count
@count_false_likes = Like.where('likes.like = ?', false).group(:news_id).count

结果是带有id的哈希并计算了喜欢。我不知道如何从负面喜欢中减去查询积极的喜欢,并为每个新闻做到这一点。

2 个答案:

答案 0 :(得分:2)

随着数据集的增长,这种查询变得极其缓慢。常见的解决方法是缓存upvotes和downvotes的数量。例如

# Table name: news
#
#  id         :integer          not null, primary key
#  title      :string           not null
#  content    :text             not null
#  scope      :string           not null
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  person_id  :integer          not null
#
#  upvotes_count   :integer     not null
#  downvotes_count :integer     not null
#  vote_result     :integer     not null

其中vote_result是缓存的upvotes_count - downvotes_count

然后只需做

News.order(vote_result: :desc).limit(10) # top 10 articles

当然,缺点是您需要维护这些缓存的计数器(在注册投票时增加/减少相应的计数器)。

答案 1 :(得分:1)

我解决了我的问题:

@most_liked_news_id = Like.group(:news_id)
                          .select('news_id, SUM(case when likes.like then 1 else -1 end) as max_positive')
                          .order('max_positive desc').map(&:news_id).first
@most_liked_news = News.find(@most_liked_news_id)