我正在创建一个rails应用程序,其中包含实现Act_As_Votable gem的用户和帖子模型。
我希望用户能够对帖子进行upvote和downvote,但也希望通过weighted_score算法对帖子进行排名和排序,该算法考虑了upvotes,downvotes和创建帖子的时间。
我的weighted_score算法来自Reddit,更好地描述了here。
我的帖子模型:
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可以动态计算,但不保存在数据库中,这意味着我无法对具有最高权重的帖子进行数据库排序。
如果我在帖子模型中创建了一个列,那么每次用户在帖子上投票时都要更新帖子表,这会使用Acts_As_Tagable gem失败的目的(因为我没有利用它的缓存能力) )。
所以我想在投票表中添加一个列以存储weighted_score(每次投票时都会计算),以及投票模型计算此分数的方法,但是宝石我运行它的发电机时不提供模型。它只创建一个投票表,我不知道如何在没有模型的情况下访问。
有关如何将这样的weighted_score列和方法添加到投票模型,或者如何以不同方式有效地存储帖子的加权分数的任何帮助,我们表示赞赏。
答案 0 :(得分:4)
acts_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
答案 1 :(得分: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
答案 2 :(得分:0)
你可以使用MYSQL开箱即用,结果不错,使用多行更容易阅读。
Post.order("
LOG10( ABS( some_score ) + 1 ) * SIGN( some_score ) +
( UNIX_TIMESTAMP( created_at ) / 450000 ) DESC
")
450000
是要调整的数字,它会给予得分与created_at更多的权重。
接近零会给新人带来更多的分量。
45000
将大致返回当天的得分450000
将大致返回本周的得分4500000
将大致返回该月的得分