Rails 3 - Как вы можете отсортировать результат запроса AR, выполнив математические вычисления для атрибутов? - PullRequest
0 голосов
/ 24 марта 2012

Я строю контроллер / представление, которое предоставляет широкий выбор рейтингов игроков (например, «Топ 10 лидеров»). Используя эту модель:

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 Query Guide, как это.

1 Ответ

2 голосов
/ 24 марта 2012

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...