-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use in-memory objects for adjustments in ItemAdjustments #1401
Use in-memory objects for adjustments in ItemAdjustments #1401
Conversation
0b8c268
to
d470868
Compare
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.
Using all_adjustments bypasses the individual `adjustments` associations (order.adjustments, line_item.adjustments & shipment.adjustments) which makes them outdated for further use.
Using order.inventory_units bypasses `line_item.adjustments` which makes them outdated for further use.
This ensures that the same object is used as the one inside `item.adjustments` so that it's kept up to date correctly
This avoids extra queries and should improve performance. It also should make refactoring easier without adding extra queries, including some upcoming tax-refactoring I'm working on.
So that the in-memory objects are updated.
This switches to update the adjustable `adjustments` instead of the promotion action adjustments. The former is most likely more important.
This keeps `item.adjustments` up to date.
This switches to update the adjustable `adjustments` instead of the tax rate adjustments. The former is most likely more important.
This keeps `line_item.adjustments` up to date.
This makes it the same as all the other `adjustments` relationships which makes the repair code in Adjustment simpler, and it makes it easier to query for duplicates. Also, use `line_item.adjustments.create` instead of `unit_cancel.adjustments.create`. The latter bypasses `line_item.adjustments` which makes them outdated for further use.
`create(:adjustment)` seems like a reasonble thing to do, but it doesn't update, e.g., `line_item.adjustments` and triggers the warning we have in place in Adjustment.
Nest :tax_adjustment factory under :adjustment factory Avoids duplicated `after_build` code.
This shouldn't happen in Solidus core anymore.
d470868
to
1e60956
Compare
order.all_adjustments.tax.destroy_all | ||
[order, *order.line_items, *order.shipments].each do |item| | ||
item.adjustments.destroy(item.adjustments.select(&:tax?)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this we should probably fix this line https://github.com/solidusio/solidus/blob/master/core/app/models/spree/tax/item_adjuster.rb#L31
and then remove the skip_destroy_adjustments
option
orders here should never have tax adjustments (they've been only on items since spree 2.2), so I don't think we need to consider that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jhawthorn thanks, updated!
This `destroy_all` was on a scope and thus could cause data to be out of sync. And, as mentioned by jhawthorn in the PR review we can move tax adjustment destroys to ItemAdjuster because: > orders here should never have tax adjustments (they've been only on > items since spree 2.2)
Thank you for those 👍 Would they actually make it into the 1.x branch, or only onto the Rails5 one? |
👍 |
@@ -6,18 +6,18 @@ class Spree::UnitCancel < Spree::Base | |||
DEFAULT_REASON = 'Cancel' | |||
|
|||
belongs_to :inventory_unit | |||
has_one :adjustment, as: :source, dependent: :destroy | |||
has_many :adjustments, as: :source, dependent: :destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this change would merit an entry in the CHANGELOG?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bbuchalter good point. I updated to @jhawthorn's solution though, so I've reverted back to has_one
.
Per PR feedback. Avoid changing the `has_many`/`has_one` relationship while still keeping in-memory objects up to date.
FYI I've added a Changelog entry for this and the related PRs. |
Looks great to me, really fantastic work, thanks 👍 and anyone that contributed eyes. |
See individual commits.
This avoids extra queries and should improve performance.
It also should make refactoring easier without adding extra queries,
including some upcoming tax-refactoring I'm working on.
The two primary commits are these:
adjustments
relationships" - a workaround for backward-compatibilityI'm not super happy with the above workaround, but I couldn't think of a better option. Also, it makes me nervous that we need a workaround like that in the first place -- it seems like this could be fragile. See, for example, the "Don't use all_adjustments in OrderAdjuster" commit. Using
all_adjustments
in the "wrong" way can result in outdated in-memory objects and thus incorrect calculations.Relates to #1252 and previous work done in #1356, #1389, and #1400.