Rails 3 中按虚拟属性排序
背景:我有一组可以投票的帖子。我想根据帖子的“投票得分”对帖子进行排序,投票得分由以下等式确定:
( (@post.votes.count) / ( (Time.now - @post.created_at) ** 1 ) )
我是目前将投票分数定义为:
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) }
目标: 此方法对我的应用程序加载时间造成了巨大影响。有没有更好、更高效的方法来完成这种排序?
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 ) )
I am currently defining the vote score as such:
def vote_score(x)
( (x.votes.count) / ( (Time.now - x.created_at) ** 1 ) )
end
And sorting them as such:
@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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用 MySQL,您可以使用查询来完成整个操作:
或者:
这将生成您的整个查询:
PS:然后您可以修改您的 Post 类以使用 SQL 版本的 Score(如果存在)。您还可以将分数函数缓存在实例中,这样您就不必在每次请求帖子分数时重新计算它:
PS:SQLLite3 等效项是:
If you are using MySQL you can do the entire thing using a query:
Or:
Which would make your entire query:
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:
P.S: The SQLLite3 equivalent is:
如果您要分配给同一个变量(在本例中这是错误的),则不应使用
sort!
,您应该将排序更改为:看起来你每次调用另一个帖子时都在计算帖子的票数,该帖子对数据库的访问量很大,并且可能是加载时间的来源,你可以使用
counter_cache
来每次投票时进行计数并将其存储在 posts 表中。这将使您只需执行一个数据库查询即可从 posts 表中加载。http://guides.rubyonrails.org/association_basics.html
You shouldn't use
sort!
if you are going to assign to the same variable (it is wrong in this case), you should change the sort to:It looks like you are counting the votes for Post each time you call another Post which is hitting the database quite a bit and probably the source of the toll on your load times, you can use a
counter_cache
to count each time a vote is made and store that in the posts table. This will make it so you only do one db query to load from the posts table.http://guides.rubyonrails.org/association_basics.html