远程关联的主动记录查询

时间:2013-11-08 15:12:14

标签: sql ruby-on-rails ruby ruby-on-rails-3 activerecord

我在记录之间有以下关系: enter image description here

鉴于 Project 记录,我需要一个与项目相关的所有资源相关的所有国家/地区的列表。任何国家都不应该出现过多次。

要做到这一点,忽略明显的性能问题,我可以为资源添加一个方法:

  def countries
    resources.flat_map{|resource| resource.countries}.uniq
  end

我的问题是双重的。

有没有办法以高效的方式实现查询?如果没有,我该如何处理这种情况呢?

[更新]

@ MarekLipka的建议是:

resources.includes(:countries).map(&:countries).flatten.uniq

然而,这导致60次点击,20个项目共计0.4秒:

  

资源加载(1.2ms)SELECT“resources”。* FROM“resources”WHERE   “resources”。“project_id”= 20 ORDER BY name

     

ResourceLocation Load(1.0ms)SELECT“resource_locations”。* FROM   “resource_locations”WHERE“resource_locations”。“resource_id”IN(97,   98,99,100,101,102,103,104,105,106,107,108,109,110,111,   112,113,114,115,116,117,118,119,120,121,122,123,124,125,   126)

     

国家/地区负载(0.4ms)SELECT“countries”。* FROM“countries”WHERE   “国家”。“id”IN(19,31,64,82,197,169,1,161,167)

[更新]

通过使用joins而不是includes,我的最新尝试速度大约是上述解决方案的两倍,每个资源的点击次数总计约为0.2秒:

Country.joins(resource_locations: {resource: :project}).where(resources: {project_id: self}).uniq

1 个答案:

答案 0 :(得分:1)

这应该没问题:

resources.includes(:countries).map(&:countries).flatten.uniq

includes方法通过预先加载适当的关联来解决N + 1查询的问题。