Skip to content

Commit

Permalink
Automatically update adjustments relationships
Browse files Browse the repository at this point in the history
So that in-memory associations stay up to date for calculations in
OrderUpdater and elsewhere.

E.g. if you do this:

    Spree::Adjustment.create!(adjustable: line_item, ...)

Then `line_item.adjustments` does not get updated if it's already
loaded.

Also this:

  source.adjustments.create!(adjustable: line_item, ...)

likewise doesn't update `line_item.adjustments`.

The code in this commit is not the most lovely code, but I couldn't
think of a better option for the time being, given that we expose all
of ActiveRecord as an interface and it's likely that extensions and/or
stores themselves have code like the above in, for example, their
promotion actions.
  • Loading branch information
jordan-brough committed Aug 24, 2016
1 parent 065657f commit 1e60956
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions core/app/models/spree/adjustment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class Adjustment < Spree::Base
validates :amount, numericality: true
validates :promotion_code, presence: true, if: :require_promotion_code?

# We need to use `after_commit` here because otherwise it's too early to
# tell if any repair is needed.
after_commit :repair_adjustments_associations_on_create, on: [:create]
after_commit :repair_adjustments_associations_on_destroy, on: [:destroy]

scope :not_finalized, -> { where(finalized: false) }
scope :open, -> do
Spree::Deprecation.warn "Adjustment.open is deprecated. Instead use Adjustment.not_finalized", caller
Expand Down Expand Up @@ -177,5 +182,21 @@ def update!(target = nil)
def require_promotion_code?
promotion? && source.promotion.codes.any?
end

def repair_adjustments_associations_on_create
if adjustable.adjustments.loaded? && !adjustable.adjustments.include?(self)
# Note: I will update this to a deprecation once I've gotten rid of all the occurrences in Solidus
puts("Adjustment was not added to #{adjustable.class}. Add adjustments via `adjustable.adjustments.create!`. Partial call stack: #{caller.select { |line| line =~ %r(/(app|spec)/) }}.", caller)
adjustable.adjustments.proxy_association.add_to_target(self)
end
end

def repair_adjustments_associations_on_destroy
if adjustable.adjustments.loaded? && adjustable.adjustments.include?(self)
# Note: I will update this to a deprecation once I've gotten rid of all the occurrences in Solidus
puts("Adjustment was not removed from #{adjustable.class}. Remove adjustments via `adjustable.adjustments.destroy`. Partial call stack: #{caller.select { |line| line =~ %r(/(app|spec)/) }}.", caller)
adjustable.adjustments.proxy_association.target.delete(self)
end
end
end
end

0 comments on commit 1e60956

Please sign in to comment.