不确定如何优化活动记录关联

时间:2011-04-11 19:40:39

标签: ruby-on-rails ruby activerecord data-access

我有一段代码通过id获取关联对象,否则初始化一个新对象。

def pick_for_game(game_id)
   picks.find_or_initialize_by_game_id(game_id)
end

挑选集合通常包含数百个项目。这两个用例是:

  1. 我想将此方法称为15-30场比赛

  2. 我想为所有游戏调用此方法

  3. 似乎当前的方法对于用例a来说是好的,但对于用例b来说是绝对可怕的。我可以根据是否如下所示急切加载选项来使这个方法变得复杂:

    def pick_for_game(game_id)
      if picks.loaded?
        new_pick = proc {
          Pick.new do |p|
            p.game_id = game_id
          end
        }
        picks.detect(new_pick) do |p|
          p.game_id == game_id
        end
      else
        picks.find_or_initialize_by_game_id(game_id)
      end
    end
    

    然而,除了使代码更清洁之外,所有案例都会选择一种方法而不是另一种方法吗?解决这个问题的其他方法吗?

1 个答案:

答案 0 :(得分:0)

假设Pick是一个模型,如果您知道game_id列表,则可以在一个查询中获取指定游戏的所有现有Picks,并仅为剩余的game_id初始化新Picks:

def picks_for_games( game_ids )
  existing_picks = Pick.all( :conditions => { :game_id => game_ids } )
  game_ids_without_picks = game_ids - existing_picks.map{ |x| x.game_id }
  new_picks = game_ids_without_picks.map { 
                |game_id| Pick.initialize_by_game_id( game_id ) 
              }
  return picks + new_picks
end

您可以根据以下内容在两种实现之间切换:

if game_ids.is_a?( Array )

b)的一个选项是在Game上为任何引用它的Picks添加一个关联,这样你就可以快速查询没有选择的游戏并为每个选择初始化一个选择。

Game.all( :conditions => { :picks => nil } ).map { |game| Pick.initialize_by_game_id( game.id ) }