我有一段代码通过id获取关联对象,否则初始化一个新对象。
def pick_for_game(game_id)
picks.find_or_initialize_by_game_id(game_id)
end
挑选集合通常包含数百个项目。这两个用例是:
我想将此方法称为15-30场比赛
我想为所有游戏调用此方法
似乎当前的方法对于用例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
然而,除了使代码更清洁之外,所有案例都会选择一种方法而不是另一种方法吗?解决这个问题的其他方法吗?
答案 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 ) }