我有Project
的模型:
class Project < ActiveRecord::Base
has many :votes
end
对于Votes
:
class Votes < ActiveRecord::Base
belongs_to :project
end
每个Project
都有1到5的投票数。为了获得平均值,我在avgVotes
中创建了一个名为project_controller
的函数。
现在,对于我的观点,我可以使用控制器提供的@projects = Project.all
,但我希望@projects
按avgVotes
的每个project
的值排序}}。
我怎样才能做到这一点?
我应该在控制器或视图中订购吗?
答案 0 :(得分:4)
您的数据库可以执行计算,Rails附带相应的caluclation methods。
假设cart.user_id = user_id
console.log(cart);
db.cart.insert(cart, function(err, data) {
console.log(data);
if (err) return next(err);
})
有一个属性Vote
(从1到5),您可以通过以下方式找到项目的平均投票值:
value
以上实际上会返回project = Project.find(1)
#=> <Project id:1>
project.votes.average(:value)
# SELECT AVG(`votes`.`value`) FROM `votes` WHERE `votes`.`project_id` = 1
#=> 2.1
,我在这里使用了一个浮点数,因为它更容易阅读。
但是为每个项目运行一次这个查询可能会很昂贵。因此,您可以apply a GROUP BY
clause在单个查询中查找所有项目的平均值:
BigDecimal
(嗯,实际上是两个查询,因为它也会获取项目)
它返回一个Vote.group_by(:project).average(:value)
# SELECT AVG(`votes`.`value`) AS average_value, project_id AS project_id
# FROM `votes`
# GROUP BY `votes`.`project_id`
对的哈希值,如:
project => average_value
(再次,您将获得{
<Project id:1> => 2.1,
<Project id:2> => 4.8,
<Project id:3> => 3.0,
# ...
}
值,而不是浮点数)
您还可以让数据库将结果从最高平均投票值排到最低:
BigDecimal
请注意,名称Vote.group_by(:project).order('average_value DESC').average(:value)
# SELECT AVG(`votes`.`value`) AS average_value, project_id AS project_id
# FROM `votes`
# GROUP BY `votes`.`project_id`
# ORDER BY average_value DESC
取决于您的属性名称。即average_value
答案 1 :(得分:2)
我认为你应该尽可能多地保持视野中的逻辑。
因此,在您的控制器中,您可以执行以下操作:
@projects = Project.all.sort_by(&:avgVotes)
请记住,这种排序效率不如:
Project.order()
因为后者在db中对结果进行了排序,但是较早的是在纯ruby中运行,这比较慢。如果你可以预先计算这些值并将它们存储在数据库中,那么你可以更快地完成这个命令。