我有一个非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查询的任何想法?
答案 0 :(得分: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关联相同,则该关联的一个实例实际上是由关联的元组加载并共享