spree/spree — pull request #4887 by radar (2014-06-30 02:46:45+00:00)
Title: Item adjustments refactoring

With my work on [spree_poro](https://github.com/radar/spree_poro), I've been able to figure out several ways that we can make calculations faster within Spree. Attempting to reproduce a small part of the Spree architecture within that project really helped out.

The first of these ways is that we can implement some style of caching, which is what the `IdentityCache` introduction to the `Order` model does. This means that instead of hitting the database and retrieving stuff from spree_orders, spree_line_items, spree_adjustments, spree_shipments and so on, we can just hit up the cache and load that entire object from there. This object would be saved to the cache whenever `current_order` is called, and so it will be available to be read from the cache on `CheckoutController#update`, which would apply modifications to that Order object and save it back to the database.

The second is to work with more in-memory objects within the tests and stop hitting the database so heavily. There's really no need to do a lot of our DB hits in the tests. Our general abusive nature towards factories is not helping the test speed at all, and so in the process of doing this work I've cut down on a couple of places that used factories and persisted objects. Everything seems to work just the same.

**With this work, I've reduced the number of queries run in core's specs from ~118k, to ~98k. The time for the tests is also 20 seconds faster (2m25s -> 2m5s).**

I've removed the ugly hack in the order state machine which would cause `set_shipments_cost` to be called in some instances when an order was read, mostly when `checkout_steps` was called. This method should be called manually now in the places that we need it, rather than called every single time. I am not sure if this breaks anything that we care about just yet... there's more work to be done on that front. It'd be nice to make sure that orders aren't going from `delivery` to `complete`, completely bypassing the payment step.

I know there was an issue about that last part, but I can't seem to find it in the four-and-a-half-thousand other issues there are on this project.

Here's what's left:

- [ ] Investigate if any more identity caching can be done for line items, shipments and their adjustments
- [ ] API tests passing
- [ ] Frontend tests passing
- [ ] Backend tests passing
- [ ] Ensure shipment cost is set correctly when transitioning from delivery to payment.