When removing a product's option type, remove its variants' associated option values

This commit is contained in:
Rohan Mitchell
2014-02-06 09:31:13 +11:00
parent 6243642cc9
commit eccea9d9ff
3 changed files with 45 additions and 0 deletions

View File

@@ -1,4 +1,10 @@
Spree::Product.class_eval do
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
# don't specify dependent => destroy on this association, it is not called. See:
# https://github.com/rails/rails/issues/7618
has_many :option_types, :through => :product_option_types, :dependent => :destroy
belongs_to :supplier, :class_name => 'Enterprise'
has_many :product_distributions, :dependent => :destroy

View File

@@ -0,0 +1,10 @@
Spree::ProductOptionType.class_eval do
after_destroy :remove_option_values
def remove_option_values
self.product.variants_including_master.each do |variant|
option_values = variant.option_values.where(option_type_id: self.option_type)
variant.option_values.destroy *option_values
end
end
end

View File

@@ -412,6 +412,35 @@ module Spree
end
end
describe "option types" do
describe "removing an option type" do
it "removes the associated option values from all variants" do
# Given a product with a variant unit option type and values
p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1)
v1 = create(:variant, product: p, unit_value: 100, option_values: [])
v2 = create(:variant, product: p, unit_value: 200, option_values: [])
# And a custom option type and values
ot = create(:option_type, name: 'foo', presentation: 'foo')
p.option_types << ot
ov1 = create(:option_value, option_type: ot, name: 'One', presentation: 'One')
ov2 = create(:option_value, option_type: ot, name: 'Two', presentation: 'Two')
v1.option_values << ov1
v2.option_values << ov2
# When we remove the custom option type
p.option_type_ids = p.option_type_ids.reject { |id| id == ot.id }
# Then the associated option values should have been removed from the variants
v1.option_values(true).should_not include ov1
v2.option_values(true).should_not include ov2
# And the option values themselves should still exist
Spree::OptionValue.where(id: [ov1.id, ov2.id]).count.should == 2
end
end
end
describe "Stock filtering" do
it "considers products that are on_demand as being in stock" do
product = create(:simple_product, on_demand: true)