【问题标题】:Not sure how to optimize active record association不确定如何优化活动记录关联
【发布时间】:2011-04-11 19:40:39
【问题描述】:

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

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

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

  1. 我想为 15-30 场比赛调用此方法

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

目前的方法似乎适用于用例 a,但对于用例 b 来说绝对糟糕。我可以根据picks是否像下面这样急切地加载,使这个方法变得复杂:

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

但是,除了使代码更简洁之外,在所有情况下选择一种方法而不是另一种方法还有什么好处吗?此问题还有其他解决方案吗?

【问题讨论】:

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


    【解决方案1】:

    假设 Pick 是一个模型,如果您知道 game_ids 列表,您可以在一个查询中获取指定 Games 的所有现有 Picks,并且只为剩余的 game_ids 初始化新 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 ) }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-10
      • 2015-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      相关资源
      最近更新 更多