8

我正在创建一个具有实现Act_As_Votable gem的 User 和 Post 模型的 rails 应用程序。

我希望用户能够对帖子进行投票和反对,但也希望通过 weighted_score 算法对帖子进行排名和排序,该算法考虑了赞成票、反对票和帖子创建时间的数量。

我的 weighted_score 算法取自 Reddit 并在此处进行了更好的描述。

我的帖子模型:

class Post < ActiveRecord::Base
  belongs_to :user
  acts_as_votable

  # Raw scores are = upvotes - downvotes
  def raw_score
    return self.upvotes.size - self.downvotes.size
  end

  def weighted_score
    raw_score = self.raw_score
    order = Math.log([raw_score.abs, 1].max, 10)
    if raw_score > 0
        sign = 1
    elsif raw_score < 0
        sign = -1
    else
        sign = 0
    end
    seconds = self.created_at.to_i - 1134028003
    return ((order + sign * seconds / 45000)*7).ceil / 7.0
  end
end

我想使用 Acts_As_Voteable gem,因为它支持缓存,可以减少硬盘写入次数并节省时间。目前,帖子的 weight_score 可以即时计算,但不会保存在数据库中,这意味着我无法对 weighted_score 最高的帖子进行数据库排序。

如果我在帖子模型中创建了一个列,那么每次用户对帖子进行投票时,我都必须更新帖子表,这违背了使用 Acts_As_Tagable gem 的目的(因为我没有利用它的缓存能力)。

所以我想在投票表中添加一列来存储 weighted_score (然后在每次投票时计算),以及投票模型的方法来计算这个分数,但是 gem 不提供当我运行它的生成器时的模型。它只创建了一个投票表,我不知道如何在没有模型的情况下访问它。

对于如何将这样的 weighted_score 列和方法添加到投票模型,或者如何以不同的方式有效地存储帖子的加权分数的任何帮助,我们将不胜感激。

4

3 回答 3

4

act_as_voteable 向您的模型添加方法以访问投票 http://juixe.com/techknow/index.php/2006/06/24/acts-as-voteable-rails-plugin/

positiveVoteCount = post.votes_for
negativeVoteCount = post.votes_against
totalVoteCount = post.votes_count

如果要添加列,可以在它创建的表上正常运行迁移。它似乎也创建了一个投票模型http://juixe.com/svn/acts_as_voteable/lib/vote.rb

于 2014-12-27T02:42:44.630 回答
1

我会将 weighted_score 列添加到您的 Post 模型并通过回调处理更新。例如:

class Post < ActiveRecord::Base

   #...

   before_save :update_weighted_score

   #...

   def update_weighted_score
     # check if some relevant variables have changed first, for example
     if cached_votes_total.changed?
        # do maths
        weighted_score = blah
     end 
   end
于 2014-12-27T05:30:34.823 回答
0

您可以使用开箱即用的 MYSQL 执行此操作,并获得不错的结果,使用多行以便于阅读。

Post.order("
  LOG10( ABS( some_score ) + 1 ) * SIGN( some_score ) + 
  ( UNIX_TIMESTAMP( created_at ) / 450000 ) DESC
")

450000是要调整的数字,它将赋予分数与 created_at 更多的权重。

接近于零会给新事物更多的权重。

  • 45000将大致返回当天的得分
  • 450000将大致返回本周的得分
  • 4500000将大致返回当月的得分
于 2016-12-16T22:20:23.013 回答