我有一些代码,每个项目都可以投票。在我的观点中,我想按照从最高到最低的投票顺序列出每个项目。
我找到了一种方法,但是有更好的方法吗?
我的方式:
控制器
class Admin::ProjectsController < ApplicationController
def index
@projects = Project.all.sort_by { |project| project.votes.count }
end
end
视图
- @projects.each do |project|
%li= project.name
%li= project.teacher_firstname
%li= project.teacher_lastname
%li= project.votes.count
我试图按照Project.votes.all.order(:desc)
的方式做一些事情,但显然这不起作用,但这就是我想要做的事情。
然后有人把我指向:counter_cache,但这似乎有点太多了。无需添加计数列。
还有其他建议吗?
更新 好的,有两件事
@ jgautsch的工作,但我很好奇,这是一种类方法不是我 想让这个实例方法?或者没关系?只是 脱掉自己?我有时会感到困惑(就像阅读文章一样 当它适用于比喻类方法时。
此外,我注意到我只获得了已经投票的项目。
即使有0票,我将如何继续显示它们?我甚至拿出了limit
和num
参数
答案 0 :(得分:2)
查看此问题:Rails 3 ActiveRecord: Order by count on association
如链接问题所述,您可以使用counter_cache并将查询保留在一个表中(此处添加列没有任何问题),或执行类似此操作(未经测试):
class Project
has_many :votes
def self.top_voted(num = 10)
select("projects.id, OTHER_ATTRS_YOU_NEED, count(votes.id) AS votes_count")
.joins(:votes)
.group("projects.id")
.order("votes_count DESC")
.limit(num)
end
end
Project.top_voted(5) # top 5 most voted projects
答案 1 :(得分:1)
有趣的问题。你可以这样做:
Project.select('*, (SELECT count(*) FROM votes WHERE votes.project_id=project.id) as vote_count').order("vote_count DESC")
丑陋,我知道,但至少它只是一个查询。
如果有完全的ORM方法可以做到这一点会很酷,例如:
Project
.select(vote_count: Vote.where("project_id = project.id").count)
.order(vote_count: :desc)
<强>更新强> 另一种功能方式:
Project
.select(
Vote
.select('count(*)')
.where('project_id=projects.id')
.to_sql.sub(/(.*)/, '*, (\1)as vote_count'))
.order("vote_count DESC")
或者我们可以通过直接使用Arel或通过投票搜索(并在项目内部加入)而不是按项目搜索(并在内部加入投票)来实现更多的ORMed。