ruby on rails -不确定如何优化活动记录关联



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

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

picks集合通常包含数百个条目。这两个用例是:

  1. 我想在15-30个游戏中调用这个方法

  2. 我想在所有游戏中调用这个方法

似乎当前的方法对于用例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

然而,在所有情况下选择一种方法而不是另一种方法除了使代码更干净之外还有什么优点吗?这个问题还有别的解决办法吗?

假设Pick是一个模型,如果你知道game_ids列表,你可以在一个查询中获取指定游戏的所有现有Pick,并且只初始化剩余game_ids的新Pick:

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上为任何引用它的pick添加一个关联,这样你就可以快速查询没有pick的游戏,并为每个Game初始化一个pick。

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

相关内容

  • 没有找到相关文章

最新更新