I have a custom sorter for product properties whic...
# support
t
I have a custom sorter for product properties which works, but is breaking pagination on the products page. I have a taxon_decorator.rb file which modifies @products if params[:sorting] is present, then sorts the products by a specific property, and paginates the resulting array. All displays well on page 1 (even if changing the per_page parameter. On any subsequent pages though, no products are returned. What doesn't make sense is that if I manually specify in the decorator the
.page
number on like 23, I can return page 2 (on page one in the app's view). The params appear to be returning correctly in the controller and in the view. Is something weird happening with the kaminari paginator that I'm missing?
e
Copy code
[18] pry(main)> Spree::Config.searcher_class.new({}).retrieve_products.joins('LEFT JOIN "spree_product_properties" ON "spree_product_properties"."product_id" = "spree_products"."id" AND "spree_product_properties"."property_id" = 1').select('"spree_products".*, "spree_product_properties"."value" AS "product_property"').reorder(:product_property).to_a.map(&:product_property)
Spree::Product Load (7.8ms)  SELECT DISTINCT "spree_products".*, "spree_product_properties"."value" AS "product_property" FROM "spree_products" INNER JOIN "spree_variants" ON "spree_variants"."is_master" = $1 AND "spree_variants"."product_id" = "spree_products"."id" INNER JOIN "spree_variants" "variants_including_masters_spree_products_join" ON "variants_including_masters_spree_products_join"."deleted_at" IS NULL AND "variants_including_masters_spree_products_join"."product_id" = "spree_products"."id" INNER JOIN "spree_prices" ON "spree_prices"."deleted_at" IS NULL AND "spree_prices"."variant_id" = "variants_including_masters_spree_products_join"."id" LEFT JOIN "spree_product_properties" ON "spree_product_properties"."product_id" = "spree_products"."id" AND "spree_product_properties"."property_id" = 1 WHERE "spree_products"."deleted_at" IS NULL AND EXISTS (SELECT "spree_prices".* FROM "spree_prices" WHERE "spree_prices"."deleted_at" IS NULL AND "spree_variants"."id" = "spree_prices"."variant_id") AND ("spree_products".available_on <= '2021-10-14 17:51:15.043779') AND ("spree_products".discontinue_on IS NULL OR"spree_products".discontinue_on >= '2021-10-14 17:51:15.044003') AND "spree_prices"."deleted_at" IS NULL AND "spree_prices"."currency" = $2 AND "spree_prices"."country_iso" IS NULL ORDER BY "product_property" ASC LIMIT $3 OFFSET $4  [["is_master", true], ["currency", "MXN"], ["LIMIT", 12], ["OFFSET", 0]]
=> ["Mug", "Mug", "Snapback Cap", "Tote", "Tote", nil, nil, nil, nil, nil, nil, nil]
[19] pry(main)>
All you need to do is to change the
AND "spree_product_properties"."property_id" = 1'
for the real property id you want to sort products by
I had to try it! and I think I got it with that ^ and pagination would still work
shorter version if all products have the property:
Copy code
Spree::Config.searcher_class.new({}).retrieve_products.with_property(Spree::ProductProperty.first.property).select("spree_products.*, spree_product_properties.value product_property").reorder(:product_property)
t
Sorry, I'm a little confused on where to put this. The longer one, and the first one you sent, returns an array of 25 property names, but they are all the same property name actually except for the last 3 which are nil. The shorter one comes back with a list of products (but only 22). I will need to sort products in each taxon upon user selection from a dropdown as params[:sorting]. Each taxon may have a different set of product_property names unfortunately.
e
Copy code
def sort_by_attributes
      return @products unless params[:sorting].present?
      sortBy = params[:sorting].presence || 'name'

      if ['name', 'amount'].include?(sortBy)
        @products.select("spree_products.*, spree_prices.amount").reorder("#{sortBy} ASC")
      else
        property = Spree::Property.find_by(name: params[:sorting])
        @products.with_property(property).select("spree_products.*, spree_product_properties.value product_property").reorder(:product_property)
      end
    end
t
This looks a lot cleaner than what I have. Thank you for your help so far. Have been trying to get that code working, but I think rails has an issue with the
.select
query method because I'm getting this and so far I haven't had luck modifying it.
Copy code
PG::UndefinedColumn: ERROR:  column "product_property" does not exist
LINE 1: SELECT DISTINCT "product_property" AS alias_0, "spree_produc...
e
try with
.reorder('spree_product_properties.value')
t
That was it! Thank you so much everything is working properly now.
e
great!!!