在Rails的虚拟属性排序3 [英] Sorting by a virtual attribute in Rails 3
问题描述
背景:我有一组文章,可以进行表决的。我想,根据它们的投得分,这是由下面的等式确定的排序文章:
BACKGROUND: I have a set of Posts that can be voted on. I'd like to sort Posts according to their "vote score" which is determined by the following equation:
((@ post.votes.count)/((Time.now - @ post.created_at)** 1))
( (@post.votes.count) / ( (Time.now - @post.created_at) ** 1 ) )
我目前正在确定中投得分为这样的:
I am currently defining the vote score as such:
def vote_score(x)
( (x.votes.count) / ( (Time.now - x.created_at) ** 1 ) )
end
和排序它们的方式:
@posts = @posts.sort! { |a,b| vote_score((b) <=> vote_score((a) }
目的::此方法需要在我的应用程序的加载时间了巨大的代价。有没有做到这种分选一个更好的,更有效的方法?
OBJECTIVE: This method takes a tremendous toll on my apps load times. Is there a better, more efficient way to accomplish this kind of sorting?
推荐答案
如果你正在使用MySQL,你可以使用查询做整个事情:
If you are using MySQL you can do the entire thing using a query:
SELECT posts.id,
(COUNT(votes.id)/(TIME_TO_SEC(NOW()) - TIME_TO_SEC(posts.created_at))) as score
FROM posts INNER JOIN votes ON votes.post_id = posts.id
GROUP BY posts.id
ORDER BY score DESC
或者
class Post
scope :with_score, select('posts.*')
.select('(COUNT(votes.id)/(TIME_TO_SEC(NOW()) - TIME_TO_SEC(posts.created_at))) as score')
.joins(:votes)
.group('posts.id')
.order('score DESC')
end
这会使你的整个查询:
Which would make your entire query:
@posts = Post.with_score.all
PS:那么您可以通过修改后的类使用得分的SQL版本,如果它是present。您也可以缓存在一个实例比分功能,所以您不必在每次请求后的得分时间重新计算的话:
P.S: You can then modify your Post class to use the SQL version of score if it is present. You can also make the score function cached in an instance so you don't have to re-calculate it every time you ask for a post's score:
class Post
def score
@score ||= self[:score] || (votes.count/(Time.now.utc - x.created_at.utc)
end
end
P.S:本SQLLite3当量为:
P.S: The SQLLite3 equivalent is:
strftime('%s','now') - strftime('%s',posts.created_at)
这篇关于在Rails的虚拟属性排序3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!