Reputation: 1827
I have a product that has_many Variants. And a variant belongs to a product. I want to display the name of the product(which can be found in Product) and the price and quantity(which can be found in Variants).
Product table:
-id
-title
-description
Variants table:
- id
- is_active(boolean)
- price
- quantity
- product_id
This is how the table looks like. And this is my attempt
def index
@products =Product.all
@display = []
@products.each do |product|
@children = product.variants.where(is_active: true).order(:price).
select(:id,:price,:quantity).first
if @children.present?
@display << {
id: product.id,
title: product.title,
description: product.description,
price: @children.price,
quantity: @children.quantity,
variant_id: @children.id
}
end
end
@display = Kaminari.paginate_array(@display).page(params[:page])
end
I need to optimize this to the maximum. Which brings me to my first question. How can I optimize this better .
And my 2nd question why when I do @products = Product.all.includes(:variants) it will actually increase the loading time instead of lowering it since I do get the variants for every product in that iteration over the whole @products array(so it should count as an N+1, I get products for each product I get variants)?
Is spliting my array of @products in 4 and making 4 threads populate display a good idea?
Upvotes: 1
Views: 127
Reputation: 3803
You should write it as;
def index
@display = Varient.joins(:product).where(is_active: true).order(:price).select('products.id as id, products.title, products.description, price, quantity, variants.id as variant_id')
end
Upvotes: 0
Reputation: 84132
Your code isn't using the eager loaded data which is why adding includes is slowing things down - it's just extra work.
In general if you call query methods ( where
, order
, etc) rails can't use the eager loaded data. Instead you can make a new association:
has_many :active_variants, -> { where(is_active: true).order(:price) }, class_name: "Variant"
Then eager load and use this association instead of the variants association.
Upvotes: 1