stoerebink stoerebink - 7 months ago 12
Ruby Question

Most efficient way to collect associated records?

For my table "Stores" I want to show some tabs with related records. There are 4 related tables, products, variant_skus, master_skus and vendor_skus. The relations are as follows:

store has_many :products
product has_many :variant_skus
variant_sku belongs_to :master_sku
master_sku has_many :variant_skus, :vendor_skus
vendor_sku belongs_to :master_sku


Now I've created a concern that I can include in a controller that collects the records from these tables for me, but whenever I open a store page it takes quite long to load, probably because of all the iterations. Is iterating through the associations to collect the records faster than just taking the IDs and querying the database? Or is there an other more efficient way of collecting the records?

when "stores"
@store.products.each do |product|
@products.push(product)
end

@products.each do |product|
product.variant_skus.each do |variant_sku|
@variant_skus.push(variant_sku)
@master_skus.push(variant_sku.master_sku)
end
end
@variant_skus = @variant_skus.uniq
@master_skus = @master_skus.uniq

@master_skus.each do |master_sku|
@vendor_skus.push(master_sku.vendor_skus)
end
@vendor_skus = @vendor_skus.uniq
end


Update: it works like:

@products = @store.products.includes(variant_skus: {master_sku: :vendor_skus})
@variant_skus = @products.map(&:variant_skus).flatten.uniq
@master_skus = @variant_skus.each.map(&:master_sku).uniq
@vendor_skus = @master_skus.map(&:vendor_skus).flatten.uniq

Answer

Try:

  when "stores"
    @products = @store.products.includes(variant_skus: {master_sku: :vendor_skus})
    @variant_skus = @products.map(&:variant_skus).uniq
    @master_skus = @variant_skus.map(&:master_sku).uniq
    @vendor_skus = @master_skus.map(&:vendor_skus).flatten.uniq
  end
Comments