Move premature Spree::Order#update prevention up a level, for even greater efficiency gains

This commit is contained in:
Rohan Mitchell
2016-01-07 11:21:25 +11:00
parent ac650ebd46
commit 257b5a9eef
3 changed files with 27 additions and 30 deletions

View File

@@ -23,13 +23,23 @@ Spree::OrdersController.class_eval do
end
def populate
populator = Spree::OrderPopulator.new(current_order(true), current_currency)
if populator.populate(params.slice(:products, :variants, :quantity), true)
fire_event('spree.cart.add')
fire_event('spree.order.contents_changed')
render json: true, status: 200
else
render json: false, status: 402
# Without intervention, the Spree::Adjustment#update_adjustable callback is called many times
# during cart population, for both taxation and enterprise fees. This operation triggers a
# costly Spree::Order#update!, which only needs to be run once. We avoid this by disabling
# callbacks on Spree::Adjustment and then manually invoke Spree::Order#update! on success.
Spree::Adjustment.without_callbacks do
populator = Spree::OrderPopulator.new(current_order(true), current_currency)
if populator.populate(params.slice(:products, :variants, :quantity), true)
fire_event('spree.cart.add')
fire_event('spree.order.contents_changed')
current_order.update!
render json: true, status: 200
else
render json: false, status: 402
end
end
end

View File

@@ -164,29 +164,21 @@ Spree::Order.class_eval do
def update_distribution_charge!
with_lock do
EnterpriseFee.clear_all_adjustments_on_order self
# Without intervention, the Spree::Adjustment#update_adjustable callback is called
# once for every (line item x fee), which triggers a costly Spree::Order#update!
Spree::Adjustment.without_callbacks do
EnterpriseFee.clear_all_adjustments_on_order self
line_items.each do |line_item|
if provided_by_order_cycle? line_item
OpenFoodNetwork::EnterpriseFeeCalculator.new.create_line_item_adjustments_for line_item
line_items.each do |line_item|
if provided_by_order_cycle? line_item
OpenFoodNetwork::EnterpriseFeeCalculator.new.create_line_item_adjustments_for line_item
else
pd = product_distribution_for line_item
pd.create_adjustment_for line_item if pd
end
end
if order_cycle
OpenFoodNetwork::EnterpriseFeeCalculator.new.create_order_adjustments_for self
else
pd = product_distribution_for line_item
pd.create_adjustment_for line_item if pd
end
end
# After fees are calculated, we update the order once
update!
if order_cycle
OpenFoodNetwork::EnterpriseFeeCalculator.new.create_order_adjustments_for self
end
end
end

View File

@@ -54,7 +54,6 @@ describe Spree::Order do
product_distribution.should_receive(:create_adjustment_for).with(line_item)
subject.stub(:product_distribution_for) { product_distribution }
subject.should_receive(:update!)
subject.update_distribution_charge!
end
@@ -67,8 +66,6 @@ describe Spree::Order do
subject.stub(:product_distribution_for) { nil }
subject.should_receive(:update!)
subject.update_distribution_charge!
end
@@ -94,8 +91,6 @@ describe Spree::Order do
OpenFoodNetwork::EnterpriseFeeCalculator.any_instance.stub(:create_order_adjustments_for)
subject.stub(:order_cycle) { order_cycle }
subject.should_receive(:update!)
subject.update_distribution_charge!
end