So in following @berkes 'Add sorting to your product page in Spree' guide, I tried to repeat with my taxons controller. However there was no difference in order, despite the scopes being applied.
Another commenter Adam shared my frustration: 'How would I make this work for taxons as well? Everything I try doesn't work'.
After a little bit of research, I figured it out.
Spree::TaxonsController applies an .order() when scoping for the products in the taxon (to maintain their assigned position, you know when you drag them around in the list in admin: /admin/taxons).
This invalidates any subsequent order (like when we try order/sort by price, etc). Trick is to remove any ORDER_BY with .reorder('') before we apply any future scopes (like :ascend_by_master_price ).
See the attached taxons_controller_decorator.rb for the working code.
The code in guide worked for the products_controller as that didn't call any scope that applied an ORDER_BY that would invalidate the sort by scopes, relevant code here.
The products_controller#index combined with our products_controller_decorator#index ultimately runs something like:
@searcher = build_searcher(params.merge(include_images: true))
@products = @searcher.retrieve_products
...
# Below same as: @products.joins(:master => :default_price).order("#{price_table_name}.amount ASC")
@products.send(:ascend_by_master_price)Which ends the sql statement in ...ORDER BY "spree_prices".amount ASC LIMIT 12 OFFSET 0.
Great that works and we get our products acending by master price.
However the taxons_controller includes a taxon (who would guess), relevant code here, applies the in_taxon scope, which applies an .order(), relevant code here. This .order() is to order by the position assigned to the product in the taxon (you know the drag interface in the admin: /admin/taxons).
The taxons_controller#show combined with our taxons_controller_decorator#show ultimately runs something like:
@searcher = build_searcher(params.merge(taxon: @taxon.id, include_images: true)) # Includes `:in_taxon` scope
@products = @searcher.retrieve_products
...
# Below same as: @products.joins(:master => :default_price).order("#{price_table_name}.amount ASC")
@products.send(:ascend_by_master_price)Which ends the sql statement in ...ORDER BY spree_products_taxons.position ASC, "spree_prices".amount ASC. Priority is given to ordering by the position, which makes the amount ordering invalid/useless.
So the solution is to remove the previous ORDER BY spree_products_taxons.position ASC by applying .reorder(''), before applying the :ascend_by_master_price scope (but we want to maintain position if no sorting param is given).
Like so in taxons_controller_decorator#show:
...
# Remove default `:in_taxon` `ORDER_BY` & apply sorting scope if `sorting` param is present
@products = @products.reorder('').send(sorting_scope) if params[:sorting].present?Which ends the sql statement in ...ORDER BY "spree_prices".amount ASC LIMIT 12 OFFSET 0 and gives us back our products in the taxon ascending by master price.
Happy days. Checkout the attached taxons_controller_decorator.rb the working code for sorting taxons.
Thank you @berkes for the original guide.