AASM kick in the balls bug / typo / misunderstanding

Pretty average AASM block right? Wrong….

I was just dealing with a bug where object.mark_sent! wasn’t saving the record.

included do
  include AASM
  aasm(:state) do
    state :in_checkout, initial: true
    state :processing
    state :available
    state :completed
    state :inactive
    state :sent

    event :start_processing! do
      transitions from: [:in_checkout, :processing, :available], to: :processing
    end

    event :processed! do
      transitions from: [:in_checkout, :processing], to: :available
    end

    event :mark_sent! do
      transitions from: [:available, :completed], to: :sent
    end

    after_all_transitions :set_aasm_timestamp
  end
end

There’s a mark_sent! event, so surely mark_sent! should change the state and save the record right? No.

event :mark_sent! do
  transitions from: [:available, :completed], to: :sent
end

This actually creates two method mark_sent! which makes the state change and it’s counterpart that also saves the record mark_sent!!. You can’t call a method with a double exclamation directly.

[26] pry(main)> e.mark_sent!!
[26] pry(main)* 
[26] pry(main)* e.send(:'mark_sent!!')

When in Vegas, don’t define mark your events with an exclamation. DOH.