diff --git a/core/app/models/spree/variant.rb b/core/app/models/spree/variant.rb index cf7852ecb7c..40226656db3 100644 --- a/core/app/models/spree/variant.rb +++ b/core/app/models/spree/variant.rb @@ -80,6 +80,11 @@ class Variant < Spree::Base after_destroy :destroy_option_values_variants + scope :template_variants, -> do + left_joins(product: { option_types: :option_values }).where(is_master: true).where.not(spree_option_values: { id: nil }).reorder(nil).distinct + end + scope :non_template_variants, -> { where.not(id: template_variants) } + # Returns variants that are in stock. When stock locations are provided as # a parameter, the scope is limited to variants that are in stock in the # provided stock locations. diff --git a/core/lib/spree/core/search/variant.rb b/core/lib/spree/core/search/variant.rb index dc964a15aca..ca9fa77259d 100644 --- a/core/lib/spree/core/search/variant.rb +++ b/core/lib/spree/core/search/variant.rb @@ -22,7 +22,7 @@ class Variant def initialize(query_string, scope: Spree::Variant.all) @query_string = query_string - @scope = scope + @scope = scope.non_template_variants end # Searches the variants table using the ransack 'search_terms' defined on the class. @@ -39,7 +39,7 @@ def results @scope.ransack(search_term_params(word)).result.pluck(:id) end - Spree::Variant.where(id: matches.inject(:&)) + @scope.where(id: matches.inject(:&)) end private diff --git a/core/spec/lib/search/variant_spec.rb b/core/spec/lib/search/variant_spec.rb index 8d210e1d81c..bb633420774 100644 --- a/core/spec/lib/search/variant_spec.rb +++ b/core/spec/lib/search/variant_spec.rb @@ -27,6 +27,16 @@ def refute_found(query_string, variant) it { refute_found("bca", variant) } end + context "with a template variant" do + let!(:option_type) { create(:option_type, option_values: [option_value]) } + let(:option_value) { build(:option_value) } + let(:product) { create(:product, option_types: [option_type], sku: "TEMPLATE") } + let(:variant) { create(:variant, product: product, sku: "NOT_TEMPLATE") } + + it { refute_found("TEMPLATE", product.master) } + it { assert_found("NOT_TEMPLATE", variant) } + end + context "by product" do it { assert_found("My Special Product", variant) } it { assert_found("My Spec", variant) } diff --git a/core/spec/models/spree/variant_spec.rb b/core/spec/models/spree/variant_spec.rb index ee8a3f58290..b24e8b413f6 100644 --- a/core/spec/models/spree/variant_spec.rb +++ b/core/spec/models/spree/variant_spec.rb @@ -7,6 +7,28 @@ let!(:variant) { create(:variant) } + describe '.non_template_variants' do + let(:option_type) { create(:option_type, option_values: [option_value]) } + let(:option_value) { build(:option_value) } + let(:product) { create(:product, option_types: [option_type]) } + let!(:variant) { create(:variant, product: product) } + + subject { described_class.non_template_variants } + + it { is_expected.to contain_exactly(variant) } + end + + describe '.template_variants' do + let(:option_type) { create(:option_type, option_values: [option_value]) } + let(:option_value) { build(:option_value) } + let(:product) { create(:product, option_types: [option_type]) } + let!(:variant) { create(:variant, product: product) } + + subject { described_class.template_variants } + + it { is_expected.to contain_exactly(product.master) } + end + describe 'delegates' do let(:product) { build(:product) } let(:variant) { build(:variant, product: product) }