Rails3-如何通过对属性进行数学运算来对AR查询结果进行排序



我正在构建一个控制器/视图,该控制器/视图提供广泛的玩家排名选择(例如"前十大排行榜")。使用此模型:

class Player < ActiveRecord::Base
  attr_accessible :name, :games_played, :games_lost, :games_won, games_exited, 
                  :total_kills, :total_deaths, :total_points, :total_coins
end

在我的控制器中,我有一些明显的查询结果要传递到我的视图中,以填充玩家排名列表:

@top_winners = Player.order("games_won DESC").limit(10)
@top_assassins = Player.order("total_kills DESC").limit(10)

我现在需要添加一些排序的排名,这是计算。示例:

@most_greedy would be sorted on:      :total_coins / :games_played
@most_lethal would be sorted on:      :total_kills / :games_played
@most_vanquished would be sorted on:  :total_deaths / (:games_lost + :games_exited)

我的方法是将所有玩家都放在一个数组中,然后使用Ruby的array.sort {| a,b | block } → new_array选项。在@most_greedy的情况下,我尝试了这个:

rich_players = Player.order("total_coins DESC").limit(30)  # only consider top 30 richest
@most_greedy = rich_players.sort {|total_coins, games_played| x / y }.slice(0, 9)

哪个生成错误:

undefined local variable or method `x' for #<PlayersController:0x007fb7dac59d08>

不幸的是,我对AR的理解和Ruby的技能都很差。我该如何让这种方法发挥作用?这类问题有不同的解决方法吗?我在AR查询指南中没有看到这样的内容。

sort不是活动记录,它是普通的旧ruby,并使用一个带有两个参数的块来比较两个对象,这两个对象将成为Player对象。

@most_greedy = rich_players.sort {|x, y| 
  (x.total_coins / x.games_played)  <=>  (y.total_coins / y.games_played)
}.slice(0, 9)

甚至更好,使用sort_by:

@most_greedy = rich_players.sort_by {|x|
  x.total_coins / x.games_played
}.slice(0, 9)

如果你想使用数据库进行计算(这可能会给出不同的结果,即,可能会找到一个不那么弱的球员,他的得分比限制在10名最富有的球员要好),你可以试试这个。。。(未经测试)

@most_greedy = Player.select('*, total_coins/games_played as greediness').order('greediness DESC').limit(10)

最新更新