Rails中Active Record Collection的复杂排序

时间:2016-03-17 04:42:39

标签: ruby-on-rails activerecord

我有一个Active Record系列的游戏,包括基础游戏和棋盘游戏。

# All Games (Base Games and Expansions)
games = current_user.games

我有一个基于不同参数过滤游戏的过滤方法。但是,我想在集合中移动基础游戏旁边的扩展。我该怎么做呢我可以通过以下方式获得基础游戏和扩展:

# Base Games
games.where(game_type: 'boardgame')

# Expansions
games.where(game_type: 'boardgameexpansion')

扩展在技术上可以有多个父母,所以你可以通过这样做来进入第一个父游戏:

my_game.parents.first

如何在games集合中找到父游戏,然后移动旁边的扩展?即使扩展可以有多个父级,我也会假设第一位父母总是可以搬到。

1 个答案:

答案 0 :(得分:1)

如果将这些集合加载到内存中,则应该执行一些数组操作:

expansions = games.includes(:parents).where(game_type: 'boardgameexpansion')
ordered_games = games.where(game_type: 'boardgame').to_a

expansions.find_each do |expansion|
  parent = expansion.parents.first
  parent_idx = ordered_games.index(parent)
  if parent_idx.nil?
    # no parent, can this happen? just add it to the end of the list
    ordered_games << expansion
  else
    # place the expansion immediatel after the parent
    ordered_games.insert(parent_idx + 1, expansion)
  end
end

大型数据集的性能不会很好,但这个简单的选项可能适合您。