diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index b6cd0bb221..258d1e0df2 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -21,7 +21,6 @@ Spree::Product.class_eval do attr_accessible :supplier_id, :primary_taxon_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size attr_accessible :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes, :images_attributes, :display_as - validates_associated :master, message: "^Price and On Hand must be valid" validates_presence_of :supplier validates :primary_taxon, presence: { message: "^Product Category can't be blank" } validates :tax_category_id, presence: { message: "^Tax Category can't be blank" }, if: "Spree::Config.products_require_tax_category" @@ -212,4 +211,23 @@ Spree::Product.class_eval do variant.is_master = false self.variants << variant end + + # Override Spree's old save_master method and replace it with the most recent method from spree repository + # This fixes any problems arising from failing master saves, without the need for a validates_associated on + # master, while giving us more specific errors as to why saving failed + def save_master + begin + if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed? || master.default_price.new_record?))) + master.save! + end + + # If the master cannot be saved, the Product object will get its errors + # and will be destroyed + rescue ActiveRecord::RecordInvalid + master.errors.each do |att, error| + self.errors.add(att, error) + end + raise + end + end end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index aca9404fb7..70bfb38227 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -25,9 +25,10 @@ module Spree it "does not save when master is invalid" do s = create(:supplier_enterprise) t = create(:taxon) - product = Product.new supplier_id: s.id, name: "Apples", price: 1, primary_taxon_id: t.id + product = Product.new supplier_id: s.id, name: "Apples", price: 1, primary_taxon_id: t.id, variant_unit: "weight", variant_unit_scale: 1000, unit_value: 1 product.on_hand = "10,000" - product.save.should be_false + expect(product.save).to be_false + expect(product.errors[:count_on_hand]).to include "is not a number" end it "defaults available_on to now" do