spree/spree — pull request #1733 by radar (2012-06-30 03:08:35+00:00)
Title: Switch from state_machine to aasm

Since #1418 didn't fly with the uptops (@BDQ), I was all "challenge accepted" this morning and set about toying with other state machine gems "for a few minutes" and then I would do some writing. It's been three hours, and no writing has been done.

Nevertheless, I think I've found what we need now in the aasm gem. This gem allows you to re-define the state machine (by clearing previous states and events and defining new ones) and I think with this we could probably provide an API like this:

```ruby
Spree::Order.class_eval do
checkout do
step :address
step :delivery
step :payment, :if => :payment_required?
step :confirmation, :if => :confirmation_required?
end
end

With of course the `cart` and `complete` states being automatically set up. The `step` method simply defines the steps that will be visible to the user.

Each `step` call would define a state transition. So by calling `step :delivery` after `step :address` you'd expect to end up with something like this in your state machine:

```ruby
event :next do
transitions :from => :address, :to => :delivery
end
```

In the cases where steps are optional, the following would happen:

```ruby
event :next do
transitions :from => :delivery, :to => :payment, :guard => :payment_required?
transitions :from => :delivery, :to => :complete
end
```
In the case of a double guard like the delivery -> payment -> complete flow, you'd expect this:

```ruby
event :next do
transitions :from => :delivery, :to => :payment, :guard => :payment_required?
transitions :from => :delivery, :to => :confirm, :guard => :confirmation_required?
transitions :from => :delivery, :to => :complete
transitions :from => :confirm, :to => :complete
end
```

I'm not quite sure how to implement at the moment, but I'll have a play around.