
November 21, 2025
State machines are one of the cleanest and most reliable ways to model workflows in software. If your system needs to move through predictable steps β orders, payments, approvals, devices, tickets β a state machine ensures everything transitions cleanly and safely.
In Ruby and Rails, theyβre extremely powerful. Hereβs a quick guide to the concept, a simple example, and a comparison of the top gems.
πΉ What Is a State Machine?

A Finite State Machine (FSM) models four things:
βοΈ States (e.g., pending, approved, rejected)
βοΈ Events that trigger transitions
βοΈ Valid paths between states
βοΈ Optional guards and callbacks
It protects your system from invalid behavior β like shipping an order before being paid.
πΉ Simple Example (No Gem)
class Order
STATES = %i[pending paid shipped delivered].freeze
attr_reader :state
def initialize
@state = :pending
end
def pay ; transition_to(:paid) if state == :pending; end
def ship ; transition_to(:shipped) if state == :paid; end
def deliver ; transition_to(:delivered) if state == :shipped; end
private
def transition_to(new_state)
puts "Transition: #{state} β #{new_state}"
@state = new_state
end
end
Great for understanding the idea β but real apps benefit from a gem.
πΉ The Most Popular Ruby State Machine Gems
1οΈβ£ AASM (Recommended for Most Rails Apps)
One of the most widely adopted solutions in the Ruby ecosystem.
Pros
- Clean, readable DSL
- Rails-friendly
- Guards, callbacks, multiple machines
- Good community support
Cons β Can get complex in large workflows β DSL flexibility can lead to messy code if not organized
Example:
aasm do
state :pending, initial: true
state :paid
state :shipped
event :pay { transitions from: :pending, to: :paid }
event :ship { transitions from: :paid, to: :shipped }
end
2οΈβ£ state_machine (Classic but Unmaintained)
The original DSL many people loved.
Pros
- Beautiful DSL
- Mature and stable historically
Cons β Not actively maintained β Many forks, fragmented ecosystem
Use for legacy apps β not ideal for new ones.
3οΈβ£ Statesman (Audit-Friendly Workflows)
A different philosophy: transitions are stored in a database table.
Pros
- Excellent for compliance and history tracking
- Clean architecture
- Great for long, complex workflows
Cons β More boilerplate β No model callbacks β Might be too heavy for simple apps
4οΈβ£ Workflow (Lightweight Ruby FSM)
Perfect if you want something tiny and fast.
Pros
- Small and simple
- Great for non-Rails Ruby apps
Cons β Less popular in Rails β Fewer advanced features
πΉ Soβ¦ Which One Should You Use?
GemBest ForProsConsAASMMost Rails appsEasy, powerfulCan get complexstate_machineLegacy appsClean DSLUnmaintainedStatesmanAuditable workflowsLogs + structureMore boilerplateWorkflowLightweight RubySimple + fastFewer features
π Final Thoughts
State machines bring clarity and safety to your domain logic. If youβre building a modern Rails app today, AASM is usually the cleanest choice. For audit-heavy systems, Statesman stands out.
