2012-03-23 66 views
0

我建立一个控制器/视图,其提供球员排名多种选择采用这种模式(如“十大排行榜”。):Rails 3 - 如何通过对属性进行算术来对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理解和红宝石技能没有我。我怎样才能使这种方法工作?这种类型的问题有不同的方法吗?我没有看到AR Query Guide中的任何内容。

回答

2

sort不是活动记录,它是普通的老红宝石,并且使用带有两个参数的块来比较这两个对象,它们将是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) 

如果你想用数据库来calulate(这可能会得出不同的结果,即可能会发现,有一个更好的成绩不太weathly球员比通过限制到10个顶级富有的玩家),你可能会尝试这...(未经测试)

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

我试着'sort_by'版本的答案,它运作良好。 'sort_by'按升序排序,所以我必须在.slice之后添加一个.reverse来得到我想要的“前10名降序”结果。谢谢! – 2012-03-24 00:48:50

+0

我也在你的答案中试过最后一个/ DB选项:Player.select(...它也有效,再次感谢。 – 2012-03-24 02:09:14

相关问题