我正在为用户个人资料创建最受欢迎的活动部分。我通过user_id提问是没有困难的,但是我很难通过相关的整数来排序然后排序:question.votes.size。这可能是一个简单的问题,但我如何排序然后将输出限制为3?如何在不滞后数据库的情况下执行此操作?最终会有很多选票被计算在内。这应该是named_scope吗?
@user_id = User.find_by_username(params[:username]).id
questions = Question.find(:all, :conditions => {:user_id => @user_id })
答案 0 :(得分:2)
我想进入并建议另一种方式,也许是更多的原生RoR。 : - )
@user = User.find_by_username(params [:username],:include => [{:questions =>:votes}]) @sorted_questions = @ user.questions.sort {| q1,q2 | q2.votes.length< => q1.votes.length}
这有许多优点:
1)没有编写SQL,维护数据库的可移植性,更易于阅读(?) 2)缓解排序计算的DB,应该更好地扩展
还有一些缺点:
1)Ruby工作更难,低负载时延迟更高,单箱效率更低 2)移动更多数据,可能减轻优势#2
理想情况下,您需要查看ActiveRecord的计数器缓存功能。它通过将子行计数非规范化为父表来自动缓存关系计数。要使它工作,所有子行操作必须通过父对象进行,但在任何情况下都是Rails的最佳实践。
在问题中使用投票计数器缓存将消除在查询中引用投票表的需要。从性能和代码美学的角度来看,这样做以及在Ruby中进行排序可能是理想的情况。
最后,我不得不承认在Rails 3上非常酷的关系代数的东西。有了它,它可能是一个超级可读的单行程序,可以生成最佳的SQL。这有多酷? : - )
答案 1 :(得分:1)
我假设每个问题都有很多票。
您可以使用
执行此操作Question.find_by_sql("
SELECT question.*, COUNT(votes.id) as vote_count
FROM questions
LEFT JOIN votes on questions.id = votes.question_id
GROUP BY questions.id
ORDER BY vote_count DESC
");
或大致相当的东西(我没有测试过)