类似于n + 1,在RoR中有两个模型

时间:2014-09-02 13:16:41

标签: ruby-on-rails

之前可能已经回答了这个问题,但我一直在搜索很多内容,而且只能找到"常规" n + 1问题。我有两个模型,区域和颜色,区域可以有多种颜色,颜色与区域相关联。假设每个区域有10个区域和5种颜色,颜色表中有50行。我想找到区域的所有颜色,具有特定的color_mode。

create_table :region do |t|
  t.string :name
end

create_table :colors do |t|
  t.references :region, index: true
  t.integer :color_mode
  t.column :color, :bigint
end

class Color < ActiveRecord::Base
  belongs_to :region
end

class Region < ActiveRecord::Base
  has_many :colors
end

我可以完成工作:

  @ids = [] 
  @colors = []
  Regions.all.each do |region|
    @ids.push(region.id)
    @colors.push(Color.find_by(region: region, color_mode: some_color).color)
  end

但这会产生n + 1个查询,我无法真正弄清楚如何更有效地进行查询。

谢谢!

2 个答案:

答案 0 :(得分:0)

我会添加第三个模型。对我来说,你应该有能力使颜色属于多个区域。

class Color < ActiveRecord::Base
  has_many :region_colors
  has_many :regions, through: :region_colors
end

class Region < ActiveRecord::Base
  has_many :region_colors, through: :region_colors
  has_many :colors
end

class RegionColor < ActiveRecord::Base
  belongs_to :region
  belongs_to :color
end

这样你可以做到

@color = Color.find(params[:id])
@colors_regions = @color.regions

答案 1 :(得分:0)

对我来说似乎是普通的n + 1查询问题。

你只需要尝试向后解决它。

Color.includes(:region).where(color_mode: something).find_each do |color|
  # color.region contains the corresponding region
end

注意:如果在Region的任何一个Color上有多个color_mode与同一{{1}}相关联,则可能会找到重复的区域。如果没有 - 那么你很高兴。