按方法值排序

时间:2016-06-22 10:36:06

标签: ruby-on-rails ruby

我有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,但我希望@projectsavgVotes的每个project的值排序}}。

我怎样才能做到这一点?

我应该在控制器或视图中订购吗?

2 个答案:

答案 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中运行,这比较慢。如果你可以预先计算这些值并将它们存储在数据库中,那么你可以更快地完成这个命令。