diff --git a/admin/app/components/solidus_admin/products/index/component.rb b/admin/app/components/solidus_admin/products/index/component.rb index 029b1c2be0..6a015ebcbd 100644 --- a/admin/app/components/solidus_admin/products/index/component.rb +++ b/admin/app/components/solidus_admin/products/index/component.rb @@ -68,7 +68,7 @@ def filters { label: option_type.presentation, combinator: 'or', - attribute: "variants_option_values", + attribute: "option_values_id", predicate: "in", options: option_type.option_values.pluck(:name, :id), } diff --git a/core/app/models/spree/product.rb b/core/app/models/spree/product.rb index 107a876759..f06df96cd2 100644 --- a/core/app/models/spree/product.rb +++ b/core/app/models/spree/product.rb @@ -57,6 +57,8 @@ class Product < Spree::Base has_many :line_items, through: :variants_including_master has_many :orders, through: :line_items + has_many :option_values, -> { distinct }, through: :variants_including_master + scope :sort_by_master_default_price_amount_asc, -> { with_default_price.order('spree_prices.amount ASC') } @@ -127,26 +129,8 @@ def find_or_build_master alias :options :product_option_types - # The :variants_option_values ransacker filters Spree::Product based on - # variant option values ids. - # - # Usage: - # Spree::Product.ransack( - # variants_option_values_in: [option_value_id1, option_value_id2] - # ).result - ransacker :variants_option_values, formatter: proc { |v| - if OptionValue.exists?(v) - joins(variants_including_master: :option_values) - .where(spree_option_values: { id: v }) - .distinct - .select(:id).arel - end - } do |parent| - parent.table[:id] - end - - self.allowed_ransackable_associations = %w[stores variants_including_master master variants] - self.allowed_ransackable_attributes = %w[name slug variants_option_values] + self.allowed_ransackable_associations = %w[stores variants_including_master master variants option_values] + self.allowed_ransackable_attributes = %w[name slug] self.allowed_ransackable_scopes = %i[available with_discarded with_all_variant_sku_cont with_kept_variant_sku_cont] # @return [Boolean] true if there are any variants diff --git a/core/lib/spree/core.rb b/core/lib/spree/core.rb index e20dbb6f54..c9ca87e119 100644 --- a/core/lib/spree/core.rb +++ b/core/lib/spree/core.rb @@ -22,8 +22,6 @@ require 'ransack' require 'state_machines-activerecord' -require_relative './ransack_4_1_patch' - # This is required because ActiveModel::Validations#invalid? conflicts with the # invalid state of a Payment. In the future this should be removed. StateMachines::Machine.ignore_method_conflicts = true diff --git a/core/lib/spree/ransack_4_1_patch.rb b/core/lib/spree/ransack_4_1_patch.rb deleted file mode 100644 index f531de330d..0000000000 --- a/core/lib/spree/ransack_4_1_patch.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -require "ransack/version" - -return unless Ransack::VERSION.start_with?("4.1.") - -module RansackNodeConditionPatch - private - - # Waiting for https://github.com/activerecord-hackery/ransack/pull/1468 - def casted_array?(predicate) - predicate.is_a?(Arel::Nodes::Casted) && predicate.value.is_a?(Array) - end - - Ransack::Nodes::Condition.prepend(self) -end diff --git a/core/solidus_core.gemspec b/core/solidus_core.gemspec index 43ec266f67..073b3ead54 100644 --- a/core/solidus_core.gemspec +++ b/core/solidus_core.gemspec @@ -43,9 +43,7 @@ Gem::Specification.new do |s| s.add_dependency 'monetize', '~> 1.8' s.add_dependency 'kt-paperclip', ['>= 6.3', '< 8'] s.add_dependency 'psych', ['>= 4.0.1', '< 6.0'] - # @note ransack 4.2 contains a bug which has not yet been addressed. - # @see https://github.com/activerecord-hackery/ransack/pull/1468 - s.add_dependency 'ransack', ['~> 4.0', '< 4.2'] + s.add_dependency 'ransack', ['~> 4.0', '< 5'] s.add_dependency 'sprockets-rails', '!= 3.5.0' s.add_dependency 'state_machines-activerecord', '~> 0.6' s.add_dependency 'omnes', '~> 0.2.2' diff --git a/core/spec/models/spree/product_spec.rb b/core/spec/models/spree/product_spec.rb index 19f6752731..561ba07c4d 100644 --- a/core/spec/models/spree/product_spec.rb +++ b/core/spec/models/spree/product_spec.rb @@ -627,13 +627,13 @@ class Extension < Spree::Base end end - context "ransacker :variants_option_values" do + describe "ransack :option_values_id_in" do it "filters products based on option values of their variants" do product_1 = create(:product) option_value_1 = create(:option_value) create(:variant, product: product_1, option_values: [option_value_1]) - result = Spree::Product.ransack(variants_option_values_in: [option_value_1.id]).result + result = Spree::Product.ransack(option_values_id_in: [option_value_1.id]).result expect(result).to contain_exactly(product_1) end @@ -644,13 +644,13 @@ class Extension < Spree::Base create(:variant, product: product_1, option_values: [option_value_1]) create(:variant, product: product_2, option_values: [option_value_1]) - result = Spree::Product.ransack(variants_option_values_in: [option_value_1.id]).result + result = Spree::Product.ransack(option_values_id_in: [option_value_1.id]).result expect(result).to contain_exactly(product_1, product_2) end it "returns no products if there is no match" do non_existing_option_value_id = 99999 - result = Spree::Product.ransack(variants_option_values_in: [non_existing_option_value_id]).result + result = Spree::Product.ransack(option_values_id_in: [non_existing_option_value_id]).result expect(result).to be_empty end @@ -662,7 +662,7 @@ class Extension < Spree::Base create(:variant, product: product_1, option_values: [option_value_1]) create(:variant, product: product_2, option_values: [option_value_2]) - result = Spree::Product.ransack(variants_option_values_in: [option_value_1.id, option_value_2.id]).result + result = Spree::Product.ransack(option_values_id_in: [option_value_1.id, option_value_2.id]).result expect(result).to contain_exactly(product_1, product_2) end @@ -674,7 +674,7 @@ class Extension < Spree::Base create(:variant, product: product_1, option_values: [option_value_1]) create(:variant, product: product_2, option_values: [option_value_2]) - result = Spree::Product.ransack(variants_option_values_in: [option_value_1.id]).result + result = Spree::Product.ransack(option_values_id_in: [option_value_1.id]).result expect(result).not_to include(product_2) end end