1

我有一个集合非 Active Record 模型,每个模型都有几个外键。我想急切地加载协会,但我正在努力采用这种方法。代码看起来像这样:

模型:

class Tuple
  attr_accessor :widget_id
  attr_accessor :woogle_id

  def self.all
    # returns a bunch of tuples with ids
  end

  def widget
    @widget ||= Widget.find(widget_id)
  end

  def woogle
    @woogle ||= Woogle.find(woogle_id)
  end
end

看法:

- Tuple.all.each do |tuple| 
  = render tuple.widget
  = render tuple.woogle

关于如何在这种情况下急切加载活动记录并避免 N+1 查询的任何想法?

4

1 回答 1

1

这段代码应该对你有用,尽管如果有一种更简洁的方法来设置@woogle@widget实例变量会很好:

def self.all
  # get a bunch of tuples with ids
  all_tuples = some_logic
  widgets = Widget.where(id: all_tuples.map(&:widget_id)).inject({}){|m, w| m[w.id] = w; m}
  woogles = Woogle.where(id: all_tuples.map(&:woogle_id)).inject({}){|m, w| m[w.id] = w; m}
  all_tuples.each do |t|
    t.instance_variable_set :@widget, widgets[t.widget_id]
    t.instance_variable_set :@woogle, woogles[t.woogle_id]
  end
end

请注意,如果元组的任何 Widget 或 Woogle 关联相同,则只有该关联的一个实例实际上是预先加载并由关联的元组共享

于 2013-04-11T03:50:17.167 回答