From 1995a4484875b8035cce74c746cc9d3ce09d1413 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Sat, 6 May 2023 13:30:25 +0100 Subject: [PATCH] Improve eager-loading on admin products page adn resolve issue with serializer For some reason eager-loaded data isn't passed to nested serializers when using associations. Defining the association as a method and passing in some optional paramaters resolves the issue. This reduces queries run by the controller action by around 75%, as well as the response times. --- app/controllers/api/v0/products_controller.rb | 2 +- .../api/admin/product_serializer.rb | 20 ++++++++++++++++--- .../api/admin/variant_serializer.rb | 6 +++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v0/products_controller.rb b/app/controllers/api/v0/products_controller.rb index 1322aa7f48..c15a3d60b3 100644 --- a/app/controllers/api/v0/products_controller.rb +++ b/app/controllers/api/v0/products_controller.rb @@ -116,7 +116,7 @@ module Api def product_query_includes [ - master: [:images], + master: { images: { attachment_attachment: :blob } }, variants: [:default_price, :stock_locations, :stock_items, :variant_overrides, { option_values: :option_type }] ] diff --git a/app/serializers/api/admin/product_serializer.rb b/app/serializers/api/admin/product_serializer.rb index d65909a521..b313d4297e 100644 --- a/app/serializers/api/admin/product_serializer.rb +++ b/app/serializers/api/admin/product_serializer.rb @@ -5,12 +5,26 @@ module Api class ProductSerializer < ActiveModel::Serializer attributes :id, :name, :sku, :variant_unit, :variant_unit_scale, :variant_unit_name, :inherits_properties, :on_hand, :price, :available_on, :permalink_live, - :tax_category_id, :import_date, :image_url, :thumb_url + :tax_category_id, :import_date, :image_url, :thumb_url, :variants, :master has_one :supplier, key: :producer_id, embed: :id has_one :primary_taxon, key: :category_id, embed: :id - has_many :variants, key: :variants, serializer: Api::Admin::VariantSerializer - has_one :master, serializer: Api::Admin::VariantSerializer + + def variants + ActiveModel::ArraySerializer.new( + object.variants, + each_serializer: Api::Admin::VariantSerializer, + image: thumb_url, + stock_location: Spree::StockLocation.first + ) + end + + def master + Api::Admin::VariantSerializer.new( + object.master, + image: thumb_url + ) + end def image_url object.images.first&.url(:product) || "/noimage/product.png" diff --git a/app/serializers/api/admin/variant_serializer.rb b/app/serializers/api/admin/variant_serializer.rb index 062ce4ceee..e4ad155914 100644 --- a/app/serializers/api/admin/variant_serializer.rb +++ b/app/serializers/api/admin/variant_serializer.rb @@ -33,7 +33,7 @@ module Api end def image - object.product.images.first&.url(:mini) + options[:image] || object.product.images.first&.url(:mini) end def in_stock @@ -43,13 +43,13 @@ module Api def stock_location_id return if object.stock_items.empty? - object.stock_items.first.stock_location.id + options[:stock_location]&.id || object.stock_items.first.stock_location.id end def stock_location_name return if object.stock_items.empty? - object.stock_items.first.stock_location.name + options[:stock_location]&.name || object.stock_items.first.stock_location.name end def variant_overrides_count