spree_related_products icon indicating copy to clipboard operation
spree_related_products copied to clipboard

Product method missing of this gem causes n+1 query unintentionally

Open channainfo opened this issue 4 years ago • 0 comments

I ty to fetch 4 (top) products per selected taxon to show on my website feed. You can see the gist here:

https://gist.github.com/channainfo/175196541df06db41da3d50eef13379e

On line 32 I get the taxon_id from the active relation which result in the Spree::Product https://gist.github.com/channainfo/175196541df06db41da3d50eef13379e#file-feed_taxon_product-rb-L32

causes spree_related_products to fire method_missing eventually trigger undesired queries as below:

  Spree::RelationType Load (0.4ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.3ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.4ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.1ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.2ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]
  Spree::RelationType Load (0.3ms)  SELECT "spree_relation_types".* FROM "spree_relation_types" WHERE "spree_relation_types"."applies_to" = $1 ORDER BY "spree_relation_types"."name" ASC  [["applies_to", "Spree::Product"]]

To work around to avoid triggering spree_related products method missing, online 32 I had to do this

# taxon_product.taxon_id == taxon.id
taxon_product.read_attribute_before_type_cast('taxon_id') == taxon.id

There should be a better way to handle this to avoid unwanted performance impact and debuggability https://github.com/spree-contrib/spree_related_products/blob/master/app/models/spree/product_decorator.rb#L51

channainfo avatar Feb 19 '21 08:02 channainfo