2012-03-23 65 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

相關問題